Compare commits

...

744 Commits

Author SHA1 Message Date
Nishant Das
b3650903ea Fix Parsing of Nested Subcommands (#9236)
(cherry picked from commit 2ffe8336fc)
2021-07-21 14:08:42 -05:00
Nishant Das
a9ee3ee06a Update Go-Ethereum (#9157)
* update

* tidy

* fix

* fix e2e

* fix e2e

* fix bad tx opts
2021-07-09 07:58:43 -05:00
Preston Van Loon
7c23d02c3e Remove cluster-pk-manager tool (#9165)
* Remove cluster-pk-manager tool

* Go mod tidy
2021-07-08 13:31:41 -05:00
Preston Van Loon
9dc3dd04c7 Update go-bitfield (#9162) 2021-07-08 08:31:40 -07:00
ahadda5
72886986ea prysm scripts should not save 404 pages (#9072)
* first .sh attempt, checked curl

* removed echo

* more meaningful msg

* prysm.bat changes

* do not save 404, using -f and grep

* removed extra line

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-07-06 23:34:42 +00:00
terence tsao
1d3a9983cc Move block interface next to generated pb (#9146)
* Move block interface next to pb

* Update fuzz build bazel

* Move interface to /proto/interface and wrapper next to generated pb

* Fix fuzz build bazel

* Add //proto/eth/v1alpha1/wrapper

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-07-06 15:34:05 +00:00
Mohamed Zahoor
cca4a8c821 exploredb tool to display bucket contents (#9116)
* add state bucket content display test case

* save work

* state db disection methods

* fix go.mod

* gazel fix

* pass the testcase if the db is not present. for CI

* get db path from env. optimize code

* update deps.bzl

* go mod tidy

* revery deps.bzl

* moved bucket content inspection to exploredb tool

* satisfy deepsource and tidy go.mod

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-07-06 15:11:11 +00:00
terence tsao
6c8fd745a4 Better import alias names (#9149) 2021-07-06 09:37:33 -05:00
terence tsao
466546bb40 Add sync committee aggregation_bits tags for minimal and mainnet (#9147)
* Add aggregation_bits tags for minimal and mainnet

* Update go-bitfield

* Go mod tidy
2021-07-03 18:59:35 -05:00
terence tsao
1ff4605398 Add priority queue tests (#9142)
* Add priority tests

* Gazelle

* bazel

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-07-02 21:54:28 +00:00
terence tsao
2ae6452cb5 Add Eth2FastAggregateVerify (#9144)
* Add `Eth2FastAggregateVerify`

* Update propose_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-07-02 19:27:08 +00:00
terence tsao
00907fd7d1 Update log test and ChainInfoFetcher interface (#9143) 2021-07-02 14:01:37 -05:00
terence tsao
1edf1f4c87 Restructure RPC packages to be future compatible (#9136)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-07-02 15:54:52 +00:00
terence tsao
877cb9f6e6 Add priority queue from hf1 (#9138)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-07-02 15:31:32 +00:00
Nishant Das
5d65ace970 Implement Doppelganger Check (#9120)
* checkpoint changes

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

Co-authored-by: Potuz <potuz@potuz.net>

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

Co-authored-by: Potuz <potuz@potuz.net>

* add in client side tests

* add ordering

* add all new test cases

* gate feature

* handle edge case

* add one more test case

* fatal error

* zahoor's review

* Update validator/client/validator.go

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

* Update validator/client/validator.go

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

* doppelganger not doppleganger

* preston's review

* add in comment

* change comment

* Fix e2e to only run new flags on the current version

* Fix bug where zero byte public keys were always sent in the request when attestation history existed. Still some tests to fix due to another bug in attester protection AttestationHistoryForPubKey.

* go mod tidy, gazelle

* Increase test size

* fix timeout, change size back to small

Co-authored-by: Potuz <potuz@potuz.net>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-07-02 12:11:09 +08:00
Preston Van Loon
2df024afc6 Return pubkey with AttestationHistoryForPubKey AttestationRecord response (#9135)
* Return pubkey with AttestationHistoryForPubKey AttestationRecord response

* Fix tests
2021-07-02 05:50:56 +08:00
Preston Van Loon
ca7b312761 Bazel: set alias targets to manual only (#9134) 2021-07-01 14:48:09 +00:00
Preston Van Loon
d6bd619429 Bazel: minimal test build transitions (#9122)
* Add build transitions for minimal config based tests

* respect existing gotags

* clean up import

* Add some commentary

* gaz

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: rauljordan <raul@prysmaticlabs.com>
2021-06-30 19:22:09 +00:00
Preston Van Loon
24d17a536c Return an error on unrecognized arguments when running default commands in Prysm (#9129)
* Return an error on unrecognized arguments when running default commands in Prysm

* fix cases for subcommands

* Deepsource suggestion
2021-06-30 16:24:04 +00:00
Raul Jordan
b23f63a064 Beacon State V2 Interface Definition With Semantic Version Paths (#9125)
* v2 state initialize and semantic paths

* ensure build

* gaz changes to ignored build files

* gaz
2021-06-30 15:06:19 +00:00
terence tsao
4fb3e05124 Add search for most profitable sync contribution (#9121)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-29 17:26:01 +00:00
terence tsao
cd3a2e87fe Naive aggregation for SyncCommitteeContribution (#9114)
* Copy CopySyncCommitteeContribution

* Update BUILD.bazel

* Add naive aggregation for sync contribution

* Gazelle

* Update deps.bzl

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-06-29 16:11:11 +00:00
Radosław Kapka
0347b4b4af Retrieve validators through v1 API in e2e (#9117)
* Retrieve validators through v1 API in e2e

* fix comment

* simplify boolean comparison
2021-06-29 09:47:59 -05:00
Preston Van Loon
0cfc16ec3b Reorder WORKSPACE go dependency registration (#9113)
* Reorder registration of dependencies so that Prysm go deps are registered first and everything else is registered after.

* Build fixes for gazelle

* Another nofuzz fix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-29 00:04:26 +00:00
terence tsao
ea34af4abf Add proposer sync contribution type (#9106)
* Add `proposerSyncContributions`

* Update BUILD.bazel

* Add dedup and tests

* Update BUILD.bazel

* Revert grpc changes
2021-06-28 13:54:33 -05:00
Mohamed Zahoor
0f2e6fb8d5 Tool for Exploring BoltDB in Human-Readable Formats (#9063)
* exploredb tool

* bucket stats tool

* bucket stats tool

* satisfy deepsource

* format error

* add flag to get the db file

* revert go get og humanize

* gazel fix

* fix merge errors

* remove bucket-stats

* satisfy deepsource

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-28 16:59:20 +00:00
Radosław Kapka
43623e1089 Handle comma-separated query parameters in API requests (#9102)
* return empty array when no peers found

* add missing query params to endpoint factory

* fix validator endpoints in endpoint factory

* peers test

* Move API param handling to separate file

* Handle comma-separated query parameters
2021-06-28 15:37:14 +00:00
Radosław Kapka
940ce0c292 Make Eth APIs flag name implementation agnostic (#9112)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-28 15:12:39 +00:00
Radosław Kapka
71f1f19334 Small API Middleware improvements (#9111)
* extract creating DefaultErrorJson objects

* do not use default http client for proxying

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-28 11:36:12 +00:00
Nishant Das
f75548ad1e Protect Against Unsafe Coefficients (#9109) 2021-06-28 11:53:03 +02:00
terence tsao
442f8d1d3c Remove old protos (#9107) 2021-06-28 07:41:37 +00:00
ahadda5
349f832bd3 No length check in AggregatePublicKeys (#9105)
* check of len and nil

* minor edit

* minor edit

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-06-27 16:13:55 +00:00
Raul Jordan
a860648960 Reduce Usage of Eth2 Terminology in Prysm (#9104)
* remove all mentions

* more changes

* folder by folder

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-26 19:00:33 +00:00
Radosław Kapka
dd0ae1bbef Move API param handling to separate file (#9101)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-26 18:42:54 +00:00
Radosław Kapka
9eb3ff6bdf Fix a few bugs in the API (#9099) 2021-06-26 11:17:45 -07:00
Radosław Kapka
b114247836 Move common gateway registration code to new package (#9092)
* Move common gateway registration code to new package

* no shared inside of beaconchain

* beacon gateway

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-25 11:02:11 +00:00
Raul Jordan
8f5c0833ff Block Stream V2 Protos (#9096) 2021-06-25 00:05:38 +00:00
Radosław Kapka
43655e6c04 Remove verbatim strings with flag names on startup (#9093)
* Remove verbatim strings with flag names on startup

* gzl

* fix visibility

* gaz

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-24 17:20:47 +00:00
Radosław Kapka
ff99a2ed40 Run text/event-stream values returned from grpc-gateway through API Middleware (#9080)
* register events handler in v1

* begin `status.Error` messages with uppercase

* something works

* handle errors

* topic comments

* handle the rest of event types

* gzl

* make code more testable + test

* better error handling

* tests

* gzl

* fix deps

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-24 16:18:28 +00:00
Raul Jordan
860716666b Add Altair Protobuf Changes to Prysm (#9087)
* all altair protobuf additions

* add altair changes to deps
2021-06-24 10:32:30 -05:00
Raul Jordan
1e99ec30cb Revert "Improve performance during CheckAttesterDoubleVotes" (#9085)
This reverts commit a958dd246b.
2021-06-23 21:19:22 +00:00
Preston Van Loon
1f6a031630 Add a test for e2e validator to run against prior release (#9042)
* Add a test for e2e validator to run against prior release

* gofmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-23 17:07:28 +00:00
Preston Van Loon
942472fc7e Add goimports check (#9075)
* Add goimports check

* lil fixes

* lil fixes

* trying to use someone elses project instead of grinding on it myself
2021-06-22 19:57:26 +00:00
Preston Van Loon
228369e95f Double java heap size for buildkite (#9073)
(cherry picked from commit 9e28840b95cc96620841053902bf22889d69ea1b)
2021-06-22 18:28:34 +00:00
Nishant Das
9ee086feaf Disable No Freelist Sync In Backups (#9069) 2021-06-21 15:14:55 +02:00
Nishant Das
6e42f1bc5d add lock (#9068) 2021-06-21 16:33:06 +08:00
Raul Jordan
4ec0d60911 Prevent Exporting False Positive Slashing Event Due to Old Prysm DB Schema Bug (#9060)
* regression test added

* better comment

* export edge case

* add case for edge test

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-21 05:15:06 +00:00
David Shoots
2583dc1279 Remove noisy / unneeded log.Error() calls (#9066) 2021-06-20 13:31:27 -07:00
Raul Jordan
a747d151ba Fix Small Type Assertion Bug in Slasher (#9061) 2021-06-18 18:50:20 +00:00
Radosław Kapka
4f3c17cf69 Make the shared/gateway package unaware of consuming services (#9050)
* gateway refactor

* test customizations

* change variable names

* fix BUILD file

* remove unused code

* move mux registration out of gateway

* fix gateway tests

* better name for struct

* fix mock endpoint factory

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-18 13:35:13 +00:00
terence tsao
a4be7c4a46 Testutil: Reset deposit cache internally (#9059)
* Reset testutil cache internally

* Fix import

* Fix test to correct error

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-18 04:05:40 +00:00
Alexander Mollohan
ae7e2764e0 Adding ability to override directory permissions for db backup (#8888)
* Adding ability to override directory permissions for db backup

* adding new flag to usage.go

* Backup now has its own directory handling method to reduce footprint of prospective change

* removing unneeded test

* fixing build error

* switching to url param for override

* stripping flag

* adding in unit tests

* fixing a test

* minor changes for testing

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-18 01:37:58 +00:00
Radosław Kapka
fbed11b380 Do not register API Middleware with validator gateway (#9055)
* Do not register API Middleware with validator gateway

* add nil checker

* revert bool

* nil check

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-18 00:38:15 +00:00
terence tsao
4d1b5f42af Better comments for aggregator functions (#9053)
* Better comments for aggregator functions

* Naming returned value
2021-06-17 17:28:19 +00:00
Mohamed Zahoor
e953804239 Process future Blocks and Attestations (#8975)
* queue future blocks

* process early attestations

* fix formatting

* fix testcases

* fix signature testcase and move verify slot time to original place

* Add testcases to test early blocks and slot processing

* added test case to cover failure case while inserting in block pending queue

* satisfy deepsource

* fix review comments

* remove invalid testcase

* do not queue blocks which are within MAXIMUM_GOSSIP_CLOCK_DISPARITY

* format fix

* added a helper to check of the block slot is within MAXIMUM_GOSSIP_CLOCK_DISPARITY

* add helper to check clock disparity and test case for the same

* deepsource fix

* satisfy deepsoruce

* sysc/service.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-17 00:17:52 +00:00
terence tsao
3c0a9455a2 Rename field ops service to att service (#9046)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-16 21:48:56 +00:00
terence tsao
7d4418e2fe Go imports (#9045)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-16 14:28:04 +00:00
Preston Van Loon
9dc4c49fbd Update web-ui to beta.4 (#9047)
* add site data

* gofmt

* fix embed

* fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-16 13:36:43 +00:00
Preston Van Loon
6971245e05 Revert "Invert attest-timely flag" (#9044)
This reverts commit 5fe98ab260.
2021-06-15 20:48:47 +00:00
Radosław Kapka
12403d249f [Feature] - API Middleware (#8926)
* HTTP proxy server for Eth2 APIs (#8904)

* Implement API HTTP proxy server

* cleanup + more comments

* gateway will no longer be dependent on beaconv1

* handle error during ErrorJson type assertion

* simplify handling of endpoint data

* fix mux v1 route

* use URL encoding for all requests

* comment fieldProcessor

* fix failing test

* change proxy port to not interfere with e2e

* gzl

* simplify conditional expression

* Move appending custom error header to grpcutils package

* add api-middleware-port flag

* fix documentation for processField

* modify e2e port

* change field processing error message

* better error message for field processing

* simplify base64ToHexProcessor

* fix json structs

* Run several new endpoints through API middleware (#8922)

* Implement API HTTP proxy server

* cleanup + more comments

* gateway will no longer be dependent on beaconv1

* handle error during ErrorJson type assertion

* simplify handling of endpoint data

* fix mux v1 route

* use URL encoding for all requests

* comment fieldProcessor

* fix failing test

* change proxy port to not interfere with e2e

* gzl

* simplify conditional expression

* Move appending custom error header to grpcutils package

* add api-middleware-port flag

* fix documentation for processField

* modify e2e port

* change field processing error message

* better error message for field processing

* simplify base64ToHexProcessor

* fix json structs

* /eth/v1/beacon/states/{state_id}/validators

* /eth/v1/beacon/states/{state_id}/validators/{validator_id}

* /eth/v1/beacon/states/{state_id}/validator_balances

* /eth/v1/beacon/states/{state_id}/committees

* allow skipping base64-encoding for query params

* /eth/v1/beacon/pool/attestations

* replace break with continue

* Remove unused functions (#8924)

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Process SSZ-serialized beacon state through API middleware (#8925)

* update field names

* Process SSZ-serialized beacon state through API middleware

* revert changes to go.mod and go.sum

* Revert "Merge branch '__develop' into feature/api-middleware"

This reverts commit 7c739a8fd7, reversing
changes made to 2d0f8e012e.

* update ethereumapis

* update validator field name

* update deps.bzl

* update json tags (#8942)

* Run `/node/syncing` through API Middleware (#8944)

* add IsSyncing field to grpc response

* run /node/syncing through the middleware

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Return HTTP status codes other than 200 and 500 from node and debug endpoints (#8937)

* error codes for node endpoints

* error codes for debug endpoints

* better comment about headers

* gzl

* review comments

* comment on return value

* update fakeChecker used for fuzz tests

* fix failing tests

* Allow to pass URL params literally, without encoding to base64 (#8938)

* Allow to pass URL params literally, without encoding to base64

* fix compile error

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Process SSZ-serialized beacon state through API middleware (#8925)

* update field names

* Process SSZ-serialized beacon state through API middleware

* revert changes to go.mod and go.sum

* Revert "Merge branch '__develop' into feature/api-middleware"

This reverts commit 7c739a8fd7, reversing
changes made to 2d0f8e012e.

* update ethereumapis

* update validator field name

* update deps.bzl

* update json tags (#8942)

* Run `/node/syncing` through API Middleware (#8944)

* add IsSyncing field to grpc response

* run /node/syncing through the middleware

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Return HTTP status codes other than 200 and 500 from node and debug endpoints (#8937)

* error codes for node endpoints

* error codes for debug endpoints

* better comment about headers

* gzl

* review comments

* comment on return value

* update fakeChecker used for fuzz tests

* fix failing tests

* Allow to pass URL params literally, without encoding to base64 (#8938)

* Allow to pass URL params literally, without encoding to base64

* fix compile error

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* unused import

* Return correct status codes from beacon endpoints (#8960)

* Various API Middleware fixes (#8963)

* Return correct status codes from `/states` endpoints

* better error messages in debug and node

* better error messages in state

* returning correct error codes from validator endpoints

* correct error codes for getting a block header

* gzl

* fix err variable name

* fix nil block comparison

* test fixes

* make status enum test better

* fix ineffectual assignment

* make PR unstuck

* return proper status codes

* return uppercase keys from /config/spec

* return lowercase validator status

* convert requested enum values to uppercase

* validator fixes

* Implement `/beacon/headers` endpoint (#8966)

* Refactor API Middleware into more manageable code  (#8984)

* move endpoint registration out of shared package

* divide main function into smaller components

* return early on error

* implement hooks

* implement custom handlers and add documentation

* fix test compile error

* restrict package visibility

* remove redundant error checking

* rename file

* API Middleware unit tests (#8998)

* move endpoint registration out of shared package

* divide main function into smaller components

* return early on error

* implement hooks

* implement custom handlers and add documentation

* fix test compile error

* restrict package visibility

* remove redundant error checking

* rename file

* api_middleware_processing

* endpoints

* gzl

* remove gazelle:ignore

* merge

* Implement SSZ version of `/blocks/{block_id}` (#8970)

* Implement SSZ version of `/blocks/{block_id}`

* add dependencies back

* fix indentation in deps.bzl

* parameterize ssz functions

* get block ssz

* update ethereumapis dependency

* gzl

* Do not reuse `Endpoint` structs between API calls (#9007)

* code refactor

* implement endpoint factory

* fix test

* fmt

* include pbs

* gaz

* test naming fixes

* remove unused code

* radek comments

* revert endpoint test

* bring back bytes test case

* move `signedBeaconBlock` to `migration` package

* change `fmt.Errorf` to `errors.Wrap`

* capitalize SSZ

* capitalize URL

* more review feedback

* rename `handleGetBlockSSZ` to `handleGetBeaconBlockSSZ`

* rename `IndexOutOfRangeError` to `ValidatorIndexOutOfRangeError`

* simplify parameter names

* test header

* more corrections

* properly allocate array capacity

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-06-15 10:28:49 -05:00
kasey
19ff25f171 fixes 9029 + a few related client-stats fixes/improvements (#9039)
- fix missing scrape logic for these metrics:
      - sync_eth1_connected
      - sync_eth1_fallback_configured
      - sync_eth1_fallback_connected
    - update readme to add more detailed source info
      and indicate unsupported metrics.
    - fix documentation bug in prometheus help text
      for powchain_sync_eth1_connected

Co-authored-by: kasey <kasey@users.noreply.github.com>
2021-06-14 23:59:15 +00:00
Raul Jordan
4551bb47fc Add Events Streaming Endpoint for Eth2 Standard API (#9001)
* begin event source support

* add in events server and proto definitions

* fmt

* add in stream support and proper building

* add in the protos

* tidy

* add structure and comments

* fmt

* revert proto changes

* only return events we explicitly request

* capture missing events needed for eth2 apis

* handle underflow

* no hash tree roots

* gazelle

* static

* race tests passing

* simplify

* handle all required events

* begin on stream tests

* correctness and abstracting method for forwarding to state feed

* genesis root

* include missing pieces

* logging

* rem and and handle return

* added mock

* add in mock

* add tests for block events

* added comprehensive tests

* radek comments

* add missing unit tests

* updatemockgen file

* viz

* done

* Update beacon-chain/rpc/eventsv1/events.go

* Update beacon-chain/rpc/eventsv1/events.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-14 16:58:08 +00:00
Radosław Kapka
77bf4bd9f0 Create ValidatorIndexOutOfRangeError (#9035) 2021-06-14 16:38:48 +00:00
terence tsao
dfd2cc751c Refactor helpers for Altair (#9026)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-11 19:29:50 +00:00
Nishant Das
fb08014146 Add Better Zero Key Checks (#9022)
* add better checks

* preston's review
2021-06-11 13:48:57 -05:00
Preston Van Loon
6981b16ecd RPC: Surface underlying error when failing to return a state. (#9024) 2021-06-11 13:50:02 +00:00
Preston Van Loon
71fd747dca Proto mirror script fix (#9020)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-11 03:05:50 +00:00
Nishant Das
7a6ce27497 Change To LRU from FIFO Cache (#8996)
* change to lru

* fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-10 21:53:34 +00:00
Raul Jordan
6eb006175a Capture ChainReorg, FinalizedCheckpoint, and NewHead Events in Beacon Node (#9011)
* capture missing events needed for eth2 apis

* handle underflow

* no hash tree roots

* gazelle

* static

* race tests passing

* simplify

* correctness and abstracting method for forwarding to state feed

* genesis root

* add in slotutil
2021-06-10 16:13:15 -05:00
Preston Van Loon
8f90e91e99 Update jwt-go library to fix CVE-2020-26160 (#9017)
* Replace github.com/dgrijalva/jwt-go with github.com/form3tech-oss/jwt-go, including security fix

* Fix to include go cast in deps.bzl and go mod

* Add gocast stub for go.mod / deps.bzl trick

* revert some changes

* Remove ignore tag

* gaz

* go mod tidy

* add build exclusion

* Go mod?

* go mod tidy
2021-06-10 13:59:34 -05:00
Alexander Mollohan
644d5bbb1a Graffiti hex support (#8894)
* more or less feature complete, needs unit tests

* Test support and concomitant refactors

* Resolving requested changes on PR

* minor fix before trying to figure out bazel

* bazel change

* minor changes requested in pr

* fixing build errors

* fixing build errors

* fixing PR feedback

* fixing PR feedback

* resolving nitpicks

* resolving nitpicks

* build failures REEEEE

* tests fail if its not this way, so this way it is

* getting the tests to pass

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-06-10 16:54:24 +00:00
Preston Van Loon
0d8dd8d280 Update mirror-ethereumapis.sh to include committer name / email (#9009)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-09 17:09:09 +00:00
Raul Jordan
bb6f00fd87 New Proto Messages Required for Event Streams (#9010)
* add event messages

* define all required event messages

* add new proto event messages

* formatting
2021-06-09 16:49:03 +00:00
Preston Van Loon
f2768c1414 Client-stats: Fail gracefully when metrics are missing (#8976)
* Client-stauts: Fail gracefully when metrics are missing

* gazelle
2021-06-07 20:37:14 +00:00
Raul Jordan
a81c4ed6a0 Protobuf Changes for Eth2 APIs EventSource Support (#8999)
* protobuf changes for event source support

* deps update

* tidy

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-07 19:29:36 +00:00
Preston Van Loon
26c4e7b527 Update prysm.sh to support Mac M1 chip (#9000)
Updated for Apple M1 users.

Co-authored-by: mrabino1 <mrabino1@gmail.com>
2021-06-07 18:51:05 +00:00
terence tsao
aa4c21d6df Run go imports (#8995) 2021-06-06 07:39:16 +02:00
Preston Van Loon
833ac0092c Fix repo name in mirror script (#8992) 2021-06-04 22:50:41 +00:00
Raul Jordan
2ee5bd12cf Improve Mirror Bash Script for EthereumAPIs (#8991)
* amend mirror script

* bash lint
2021-06-04 16:15:19 +00:00
Preston Van Loon
d4aa4bc258 Remove unused ClosestPowerOf2 method (#8990) 2021-06-04 15:03:18 +00:00
Radosław Kapka
1ea042dd6e Do not use proto casing in v1alpha1 API JSON fields (#8988) 2021-06-04 16:03:40 +08:00
Raul Jordan
dd10a3ab5d Fix EthereumAPIs Mirror Script (#8986) 2021-06-03 21:30:24 +00:00
Raul Jordan
8d428606a2 Mirror EthereumAPIs Bash Script (#8980)
* mirror script

* revert

* add in final script

* comments
2021-06-03 21:05:33 +00:00
terence tsao
8433a313f0 Enhance att sig set checks (#8978)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-03 15:30:46 +08:00
Preston Van Loon
693fdf87bb Add clientstats spec as a README.md (#8977)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-03 00:13:31 +00:00
Raul Jordan
5aac06f04e Move EthereumAPIs Into Prysm (#8968)
* begin move

* use same import path

* imports

* regen protos

* regen

* no rename

* generate ssz

* gaz

* fmt

* edit build file

* imports

* modify

* remove generated files

* remove protos

* edit imports in prysm

* beacon chain all builds

* edit script

* add generated pbs

* add replace rules

* license for ethereumapis protos

* change visibility

* fmt

* update build files to gaz ignore

* use proper form

* edit imports

* wrap block

* revert scripts

* revert go mod
2021-06-02 18:49:52 -05:00
Raul Jordan
1d2fc60ba7 Checkin Generated Protobufs and Proto Files for EthereumAPIs (#8973)
* generated

* add ignore

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-02 20:20:11 +00:00
kasey
2b6c7e7b37 use urfave defaulting method for correct help text (#8972)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-06-02 19:47:47 +00:00
Preston Van Loon
fc898d541f Update prysm scripts to support client-stats, deprecate slasher (#8971) 2021-06-02 14:06:59 -05:00
Nishant Das
91bd477f4f Add Metadata V2 Object and Interface (#8962)
* checkpoint changes

* gaz

* add error check

* gaz

* fix tests

* fix tests

* terence's review

* terence's review

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-06-02 13:44:34 +08:00
Preston Van Loon
ef20f2da7e Altair: new protos/state object (#8907)
* Altair: new protos/state

* Undo changes in proto/migration/migration.go

* Change proto/beacon/p2p/v1/generated.ssz.go to 0644

* Update proto/beacon/p2p/v1/types.proto

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

* PR Feedback: rename SyncCommitteeSigningData to SyncAggregatorSelectionData

* 644

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-06-02 03:07:13 +00:00
Nishant Das
8a6e2a33a2 Fix Interop Mode (#8961) 2021-06-02 02:45:10 +00:00
aliask
eb1d122aec Feature/debian packages (#8872)
* Basic build targets for debian packages

* Add comments to config files

* Harden beacon-chain systemd service

* Add install scripts to set users and folders up

* Rename bazel target, fix service files

* Extra service hardening, cleanup install scripts

* Fix linting issues

* //shared:version_file run local only

* gazelle

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-06-01 15:44:24 +00:00
terence tsao
638e76cbd7 Sort imports (#8959) 2021-05-31 20:47:30 +02:00
Ivan Martinez
bb8625ede5 Remove stack trace from eth1 connection errors (#8957) 2021-05-28 21:25:54 +00:00
Ivan Martinez
40b4079924 Update deprecated function usages (#8953)
* Clear deprecated usages within Prysm

* Remove deprecatd usages where possible

* Update
2021-05-28 08:57:47 +02:00
Nishant Das
6bb3cc45ef Add Nested Nil Checks To Wrapper (#8951)
* add checks

* fix
2021-05-27 16:07:51 +00:00
Ivan Martinez
e97f6cfdbf ETH2 APIs: Handle invalid validator status as error (#8946)
* Handle invalid validator status as error

* Change text

* Fix review comments

* Remove nil status check

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-05-27 06:44:36 +00:00
terence tsao
d5f4385525 Copy to return interface (#8950) 2021-05-26 17:54:06 -07:00
kasey
8094c1c4c5 regenerate ssz types w/ variable-len bounds checks (#8936)
* regenerate ssz types w/ variable-len bounds checks

using the code in this PR:
https://github.com/ferranbt/fastssz/pull/45

* updating with improved bounds checking

* updating pinned fastssz dependency to newest

* removing redundant higher bounds checks

* regenerate again w/ new fastssz
2021-05-26 16:47:06 -05:00
terence tsao
276d03553c Block interface clean up (#8947) 2021-05-26 11:33:46 -07:00
Nishant Das
caf9bdbc6f Use Block Interface Across Prysm (#8918)
* commit initial work

* checkpoint current work

* gaz

* checkpoint

* req/resp changes

* initial-sync

* finally works

* fix error

* fix bugs

* fix issue

* fix issues

* fix refs

* tests

* more text fixes

* more text fixes

* more text fixes

* fix tests

* fix tests

* tests

* finally fix builds

* finally

* comments

* fix fuzz

* share common library

* fix

* fix

* add in more defensive nil checks

* add in more defensive nil checks

* imports

* Apply suggestions from code review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Apply suggestions from code review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update shared/interfaces/block_interface.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update shared/interfaces/block_wrapper.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update shared/interfaces/block_interface.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* imports

* fix bad changes

* fix

* terence's review

* terence's review

* fmt

* Update beacon-chain/rpc/beacon/blocks.go

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

* fix tests

* fix

* fix all tests

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-05-26 16:19:54 +00:00
Preston Van Loon
7b55213e6d Refactor attestationDelta to reuse the sqrt value of active current epoch (#8945)
* Refactor attestationDelta to reuse the sqrt value of active current epoch

* use baseRewardsPerEpoch
2021-05-26 09:37:35 -05:00
Ivan Martinez
d5ad15ed80 ETH2 APIs: Implement Validator Status support (#8940)
* Update protos for new changes

* Begin implementing validator status

* Add support for validator status to state/validators

* Fix nil pointer
2021-05-26 00:24:29 -04:00
terence tsao
2e322bdf6d Add missing finality spec tests (#8939)
* Remove unused functions

* Add finality spec tests

* Gazelle

* Add minimal tag to BUILD.bazel
2021-05-26 08:18:51 +08:00
terence tsao
5fe98ab260 Invert attest-timely flag (#8827) 2021-05-25 07:22:12 -07:00
Zahoor Mohamed
a958dd246b Improve performance during CheckAttesterDoubleVotes (#8927)
* de-normalize attestationDataRootsBucket to improve performace in CheckAttesterDoubleVotes

* parallize processing of every attestation

* fix double vote test case to take care of jumbled double votes due to parallel processing

* remove attestationRecordsBucket totally and take care of pruning

* missed out build file

* fix review comments

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-25 13:02:18 +05:30
Ivan Martinez
aa0fb058c6 ETH2 APIs: Update protos for new ethapis changes (#8920)
* Update protos for new changes

* Fix

* Fix deps

* Fix build

* Include newer changes to ethapis

* Fix

* Fix import

* Do not return unconnected peers
2021-05-24 20:02:01 -05:00
Preston Van Loon
0cbdce6bd6 Remove unused sszgen dependency (#8934)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-24 17:26:57 +00:00
Radosław Kapka
5ae6e83c7f Update deps.bzl after updating grpc-gateway dependency (#8933) 2021-05-24 16:18:26 +00:00
Radosław Kapka
180b8447f7 Update grpc-gateway dependency (#8929) 2021-05-24 09:27:50 -05:00
Nishant Das
503ec126e1 Fix Panic When Accessing State Frequently (#8928)
* fix issue

* dont allocate for existence checks

* radek's review
2021-05-24 06:52:33 +00:00
Nishant Das
76cdbaca22 Interface Analyzer (#8923) 2021-05-23 21:55:42 -07:00
terence tsao
09d7efe964 Remove unused functions (#8924) 2021-05-23 09:36:46 +02:00
Preston Van Loon
7dc3d7fc60 Write generated ssz files as non-executable 644 (#8909)
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-21 16:27:33 +00:00
Preston Van Loon
59897b78ff IntegerSquareRoot improvements (#8910)
* Add slower, but more precise sqrt method

* nofuzz
2021-05-21 11:02:16 -05:00
Ivan Martinez
f4d6e91e72 ETH2 APIs: Add spans and remove unused Server fields (#8916)
* Add spans and remove unused Server fields

* Remove more
2021-05-20 14:56:53 -05:00
Ivan Martinez
213369f5d0 Fix testing for attestation pools endpoint (#8914)
* Fix testing for attestation pools endpoint

* Remove
2021-05-20 18:59:25 +00:00
Ivan Martinez
8aa909de2d ETH2 API: Implement v1/state/validator endpoints (#8896)
* Implement validator endpoints

* Import

* Fix errors

* Add comments and fix naming :wq

* Fix functions to access state once

* Optimization for slots

* Test more

* Fix

* test listing committees for specific epoch

* Fix error retrurn

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: rkapka <rkapka@wp.pl>
2021-05-20 07:41:39 +00:00
Preston Van Loon
36e9edd654 Minor changes from hf1 branch (#8906)
* Copy new slot helpers from hf1 branch

* Make HandleEth1DataSlice public for altair
2021-05-19 16:11:48 +00:00
Ivan Martinez
9db4eba72b ETH2 API: Implement ListPoolAttestations endpoint (#8902)
* Implement ListPoolAttestations

* Spacing

* add lil doc

* Fix testing and rework logic
2021-05-19 09:55:24 -05:00
Radosław Kapka
fe440bc0eb Copy slice when exiting all keys with --exit-all (#8897)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-18 17:17:42 +00:00
terence tsao
f68e0846ba Ran go imports (#8898) 2021-05-18 16:11:02 +00:00
terence tsao
f2a2d5d43c Fix typo (#8899) 2021-05-18 08:33:52 -07:00
Preston Van Loon
f2fe1f7683 Use ExecuteStateTransition in onBlock (#8865)
* Refactor ExecuteStateTransition to use ExecuteStateTransitionNoVerifyAnySig and then verify the signatures. This reduces duplicated code paths.

* Use refactored method from PR #8864

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-17 19:52:15 +00:00
Nishant Das
35dc8c31fa Add in Context For Req/Resp (#8895)
* Add in context

* use better function signatures

* add in chainservice

* fix rpc requests

* add in test

* fix tests

* add in comments

* Update beacon-chain/sync/rpc_chunked_response.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update beacon-chain/sync/rpc_send_request.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* rename files

* fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-17 19:25:59 +00:00
Radosław Kapka
519e1e4f4a Decode peer ID properly when fetching peer (#8883)
# Conflicts:
#	beacon-chain/rpc/nodev1/node_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-17 18:58:13 +00:00
Ivan Martinez
2f10b1c7b1 Change gogoproto compiler to protoc-gen-go-cast (#8697)
* Remove gogoproto compiler

* Remove more gogoproto

* Improvements

* Fix gengo

* More scripts

* Gazelle, fix deps

* Fix version and errors

* Fix gocast for arrays

* Fix ethapis

* Fixes

* Fix compile errors

* fix go.mod

* //proto/... builds

* Update for protov2

* temp fix compilation to move on

* Change everything to emptypb.empty

* Add grpc to proto/slashings

* Fix almost all build failures

* Oher build problems

* FIX THIS FUCKING THING

* gaz literally every .bazel

* Final touches

* Final final touches

* Fix proto

* Begin moving proto.Marshal to native

* Fix site_data

* Fixes

* Fix duplicate gateway

* Fix gateway target

* Fix ethapis

* Fixes from review

* Update

* Fix

* Fix status test

* Fix fuzz

* Add isprotoslice to fun

* Change DeepEqual to DeepSSZEqual for proto arrays

* Fix build

* Fix gaz

* Update go

* Fixes

* Fixes

* Add case for nil validators after copy

* Fix cast

* Fix test

* Fix imports

* Go mod

* Only use extension where needed

* Fixes

* Split gateway from gengo

* gaz

* go mod

* Add back hydrated state

* fix hydrate

* Fix proto.clone

* Fies

* Revert "Split gateway from gengo"

This reverts commit 7298bb2054.

* Revert "gaz"

This reverts commit ca95256570.

* Merge all gateway into one target

* go mod

* Gaz

* Add generate v1_gateway files

* run pb again

* goimports

* gaz

* Fix comments

* Fix protos

* Fix PR

* Fix protos

* Update grpc-gateway and ethapis

* Update ethapis and gen-go-cast

* Go tidy

* Reorder

* Fix ethapis

* fix spec tests

* Fix script

* Remove unused import

* Fix fuzz

* Fix gomod

* Update version

* Error if the cloned result is nil

* Handle optional slots

* ADd more empty checks to clone

* Undo fuzz changes

* Fix build.bazel

* Gaz

* Redo fuzz changes

* Undo some eth1data changes

* Update go.mod

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

* Undo clone beacon state

* Remove gogo proto more and unused v1_gateway

* Add manual fix for nil vals

* Fix gaz

* tidy

* Tidy again

* Add detailed error

* Revert "Add detailed error"

This reverts commit 59bc053dcd.

* Undo varint changes

* Fix nil validators in deposit test

* Commit

* Undo

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-17 18:32:04 +00:00
Radosław Kapka
e254e8edcc Simplify handling hex state ID (#8890)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-05-17 09:56:00 +02:00
Nishant Das
e6a1d5b1b9 Refactor RPC Topic Construction (#8892)
* check in changes

* goimports

* export it

* add new rpc type
2021-05-15 08:58:56 +08:00
terence tsao
bc27a73600 Various code cleanups (#8889) 2021-05-13 08:29:14 +02:00
Nishant Das
4ef5c9ad15 add it in (#8885) 2021-05-12 15:59:26 +08:00
Radosław Kapka
ddab82e52a Handle undiscovered peers when listing peers (#8882)
* Handle undiscovered peers when listing peers

* off by 1 fix
2021-05-11 19:11:34 +02:00
Radosław Kapka
8fe26e7c84 Serialize nil ENR record (#8881) 2021-05-11 08:31:43 +00:00
Radosław Kapka
f97c7ee1da Initialize VoluntaryExitsPool and BlockReceiver in rpc server (#8876)
* Initialize `VoluntaryExitsPool` in rpc server

* initialize `BlockReceiver`
2021-05-11 07:16:13 +00:00
terence tsao
ad4fadb36a Minor clean up on mixing length root (#8875)
* Minor clean up on mixing length root

* Update root size to 32

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-05-10 22:39:53 +00:00
Nishant Das
255354f27e Fallback For Deposit Trie Creation (#8869)
* fallback

* make it an error

* comment

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

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

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-05-10 07:34:10 +08:00
Preston Van Loon
050b244fa6 Fix rules_docker dependency. See bazelbuild/rules_docker#1814 (#8867)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-07 17:38:22 +00:00
Preston Van Loon
ab6d8486fb Update golang to 1.16.4 (#8868) 2021-05-06 21:55:26 +00:00
Preston Van Loon
b628b5f8ca Refactor ExecuteStateTransition to use ExecuteStateTransitionNoVerifyAnySig (#8864)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-05-06 09:15:37 +00:00
ahadda5
ac4fe2db5a Czech language support from go-bip39 incorporated (#8861)
* added Czech from go-bip39

* go mod tidy

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-05-05 20:51:05 +00:00
Preston Van Loon
2f66d1a46c Use mock web3/powchain for fuzz test (#8866)
* Use mock web3/powchain for fuzz test

* gofmt

* build viz
2021-05-05 20:18:55 +00:00
Nishant Das
60c6cf7438 reduce map copies (#8860) 2021-05-05 16:28:35 +08:00
ahadda5
8dd2915d3c Unify gRPC Gateways into Single, Shared lib (#8799)
* moved validator/rpc/gateway under shared,  validator/rpc/web is not visiable to the new shared gateway

* decided to have one lib with two methods if needed, status and stop are the same, however New and Start are not

* moved beacon's gateway to shared and moved the main func to its own /server folder

* goftm

* gofmt

* removed the extra loggin

* reduce visibility

* tighter visibilty of the shared lib for beacon and validator only for now

* fix patterns , ctx needs to be first param

* fix comments

* gofmt

* added enum for the caller id

* added unit test for gateway

* deprecated .WithDialer to .WithContextDialer

* changed the string callerId to uint8, and rearranged the Gateway struct based on the compiler

* fix 1 based on comment

* iota type

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-04 17:20:58 +02:00
terence tsao
3c9b9e7bf5 Add interop write block and state to disk (#8840)
* Add interop write block and state to disk

* Comment why false

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-04 03:42:06 +00:00
kasey
a090650446 fixes #8848 -- scrape validator_(total|active) (#8858)
fixes #8848 -- scrape validator_total, validator_active
2021-05-03 17:24:27 -05:00
kasey
dace0f9b10 cli to push metrics to aggregator service (#8835)
* new prometheus metrics for client-stats metrics

* adds client-stats types beacause they are
  used by some of the prometheus collection code.
* new prometheus collector for db disk size
* new prometheus collector for web3 client
  connection status

* adds client-stats api push cli in cmd/client-stats

* adds api metadata to client-stats collector posts

* appease deepsource

* mop up copypasta

* use prysm assert package for testing
2021-05-03 09:57:26 -05:00
terence tsao
a6e1ff0e63 Run go imports (#8851)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-05-03 13:44:58 +00:00
terence tsao
1dde588932 Revert "Invert next-slot-state-cache flag (#8830)" (#8855)
This reverts commit 64bd9dba9b.
2021-05-03 08:04:45 +08:00
Nishant Das
54d4d39ea1 Revert "Simplify Effective Balance Calculation (#8743)" (#8844)
* Revert "Simplify Effective Balance Calculation (#8743)"

This reverts commit 45d2df1af7.

* add flag
2021-05-01 13:07:38 -05:00
kasey
7be6fc1780 new prometheus metrics for client-stats metrics (#8834) 2021-04-30 13:37:38 -07:00
Radosław Kapka
2fdfda2804 Fix remote keymanager's dynamic key reload (#8817)
* Fix remote keymanager's dynamic key reload

* wait for activation test

* runner test

* rename mock creation func

* fix compile error

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-30 15:15:22 +00:00
Nishant Das
a063952abe Fix Script (#8842)
* enable script

* add permission in

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-30 14:58:29 +00:00
Radosław Kapka
1a00121e60 Correct documentation for DepositsNumberAndRootAtHeight (#8843)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-30 14:40:42 +00:00
terence tsao
8fffa6c92a Remove junk files (#8846) 2021-04-30 16:20:14 +02:00
terence tsao
64bd9dba9b Invert next-slot-state-cache flag (#8830)
* Invert `next-slot-state-cache`

* Go fmt

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-04-30 12:47:44 +00:00
Preston Van Loon
f2767f4f8d Update github.com/grailbio/bazel-toolchain. Fixes #8072 (#8839) 2021-04-29 14:57:16 +00:00
Nishant Das
71f53d908f Add Stricter Checks To The Deposit Cache (#8838)
* add stricter checks

* fix tests
2021-04-29 14:24:13 +02:00
terence tsao
7b8e48d80e Invert proposer-atts-selection-using-max-cover flag (#8828)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-04-28 13:44:13 +00:00
Nishant Das
b6c50df435 Add New Method to Fuzz State (#8823) 2021-04-28 10:17:36 +00:00
Preston Van Loon
9b697d2c12 Partially revert PR #8809 (#8829) 2021-04-28 17:02:32 +08:00
Victor Farazdagi
d1a952a6fc Spec tests: improve readability of rewards tests output (#8826)
* Spec tests: improve readability of rewards tests output

* fix minimal tests

* remove redundant var

* simplify
2021-04-27 16:14:11 +00:00
Nishant Das
58a81c704b Remove Missing Logs Method (#8825)
* remove missing logs method

* gaz

* remove unused var
2021-04-27 19:12:47 +08:00
Nishant Das
5c9f361903 validate big num better (#8822) 2021-04-27 14:46:47 +08:00
Nishant Das
ef9f6c5b4d Initialize Data Correctly For Powchain Service (#8812)
* initialize index correctly

* comments

* review comments

* Update beacon-chain/powchain/service.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-25 00:11:15 -05:00
Preston Van Loon
424e115331 Independent eth1 voting (#8811) 2021-04-24 18:32:45 -07:00
Radosław Kapka
f1d7c0f2c9 Create a new wallet on accounts import only when necessary (#8801)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-24 08:26:41 +00:00
Raul Jordan
3d96e3c142 Amend DepositNumberAndRootAtHeight Function to Fix Off-By-One (#8809)
* amend deposit cache and add comprehensive unit tests to fix off-by-one error

* fix tests

* still need to +1 deposit index
2021-04-24 08:02:34 +00:00
Raul Jordan
8cda50f179 Optimized Slasher Database Methods (#8805)
* slasher kv additions

* gaz

* pass tests
2021-04-23 12:06:13 -05:00
Nishant Das
3574ee177d vendor codecov script (#8803) 2021-04-23 09:50:03 -05:00
Victor Farazdagi
386b69f473 Fix comments (#8802)
* fix incorrect exported name in comments

* add comments to exported methods
2021-04-23 12:06:05 +00:00
Victor Farazdagi
648e360842 Refactor shared/testutil/spectest.go (#8800)
* Refactor shared/testutil/spectest

* update operations

* update epoch_processing

* rename spectest.go
2021-04-22 16:34:00 +00:00
Victor Farazdagi
23ff14c34b Move spectests into a separate package (#8798)
* move general/phase0/bls tests

* phase0/operations tests

* phase0/sanity/blocks

* fix import

* phase0/sanity/slots

* phase0/sanity/slots minimal

* phase0/epoch_processing tests

* phase0/rewards tests

* simplify

* more simplification

* phase0/shuffling tests

* phase0/ssz_static tests

* spectest/utils

* fix build

* readme

* update test sizes

* update readme
2021-04-22 14:53:30 +00:00
Kevin Lu
e52df323f7 Added public/private flags for IP address white/blacklisting (#8648)
* Added public/private flags for IP address white/blacklisting

* Provided reference docs for private IP address ranges

* Formatting changes and inline comments for private ip address specification

* @nisdas feedback, commentary fixes

* Added in inverse case where we allow for private address

* changed helper function to take in multiaddr Action as argument, syntax changes for control logic

* minor refactoring to control flow of configFilter and private addr filter helper function

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-04-21 06:25:30 +00:00
Victor Farazdagi
823f7c99d2 Update spec tests (#8792)
* update path to minimal tests

* update specs testutils

* fix attestation_test

* attester_slashing_test

* fix block_header_test

* block_processing_minimal

* core/blocks minimal spectests

* epoch_processing minimal spectests

* slot_processing minimal spectests

* bls spectests

* update mainnet tests

* fix remaining tests

* gazelle
2021-04-20 23:54:06 +00:00
Raul Jordan
711f527efb Amend E2E Test Path (#8793) 2021-04-20 16:54:38 +00:00
Raul Jordan
af8f444166 Upgrade Bazel Go-Ethereum (#8791)
* upgrade bazel go ethereum

* tidy
2021-04-20 15:28:07 +00:00
Raul Jordan
2634430f67 Update Go-Ethereum Dependency (#8788) 2021-04-20 06:57:26 -07:00
terence tsao
70dc22aa9a Fix redundant err check (#8790) 2021-04-20 02:25:16 +00:00
Everest Stefan Munro-Zeisberger
ad269ee147 Set up Prysm for fuzz testing on Fuzzbuzz (#8789)
* Wrap beacon fuzz tests in go-fuzz compatible test functions

* Add fuzzbuzz.yaml
2021-04-19 19:00:46 +00:00
Nishant Das
cff7dbd015 Add Eth1 Header Timestamp Check (#8771)
* add time check

* unit test

* fix

* Update beacon-chain/powchain/service.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-04-17 13:55:41 +00:00
Preston Van Loon
afc0ace624 POW: remove context from log message (#8782) 2021-04-16 19:16:36 +00:00
terence tsao
400e42cc2d Reuse ProcessBlockForStateRoot (#8781) 2021-04-16 10:18:59 -07:00
Victor Farazdagi
59ee339497 Move TestMain into dedicated file (#8779)
* Move TestMain into dedicated file

* update db_test

* formatting
2021-04-16 16:25:28 +00:00
Radosław Kapka
c53d0e1c5f Codecov: ignore testing directories (#8777)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-16 08:44:36 -05:00
Raul Jordan
02a8ae7f36 Validator RPC Accounts Voluntary Exit (#8776)
* begin voluntary exits RPC

* added in exit logic

* complete exit func

* revert

* capitalize

* revert

* import

* rpc voluntary exit test

* fmt
2021-04-16 09:46:38 +02:00
terence tsao
a4ff97d24b Refactor signature function's argument (#8773) 2021-04-15 11:35:53 -07:00
Victor Farazdagi
3d3b9d1217 Spec checker tool (#8722)
* Add specdocs static code analyzer

* docs pulling script

* update content pulling script

* add test

* better parsing of incoming docs

* update test

* implements analyzer

* separate tool

* remove analyzer code

* cleanup

* deep source fixes

* untrack raw specs files

* add back phase0 defs

* update spec texts

* re-arrange code

* updated spec list

* cleanup

* more comments and readme

* add merkle proofs specs

* add extra.md

* mark wrong length issue

* update readme

* update readme

* remove non-def snippets

* update comment

* check numrows

* ignore last empty line

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-15 14:54:07 +00:00
terence tsao
169cd78bbd Refactor process operation function arguments (#8767)
* Pass slash validator func as argument

* Refactor ProcessBlockHeaderNoVerify

* Refactor Eth1Data and Randao

* Refactor ProposerSlashing

* Refactor AttesterSlashing

* Refactor VoluntaryExit

* Add VerifyNilBeaconBlock to ProcessBlock

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-04-15 13:58:54 +00:00
Nishant Das
405e2a1a03 Thread Context for HTR Methods (#8770)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-04-15 12:17:55 +00:00
Shay Zluf
d77c298ec6 Support authorised access to web 3 providers (#8075)
* jwt access token impl

* use secret or jwt

* rename

* separate method for splitting auth

* usage update

* Update beacon-chain/flags/base.go

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

* Update beacon-chain/node/node.go

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

* make things work

* removed unused code

* better, more flexible authorization

* move types and function to proper packages

* fix checking if endpoint is not set

* fix existing tests

* rename Endpoint field to Url

* Tests for HttpEndpoint

* better bearer auth

* tests for endpoint utils

* fix endpoint registration

* fix test build

* move endpoint parsing to powchain

* Revert "fix existing tests"

This reverts commit ceab192e6a.

* fix field name in tests

* gzl

* add httputils dependency

* remove httputils dependency

* fix compilation issue in blockchain service test

* correct endpoint fallback function and tests

* gzl

* remove pointer from currHttpEndpoint

* allow whitespace in auth string

* endpoint equality

* correct one auth data Equals test case

* remove pointer receiver

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-15 11:02:02 +00:00
Radosław Kapka
2c6549b431 Tests for beacon-chain/node/config.go (#8769)
* Tests for `beacon-chain/node/config.go`

* gzl

* change tested value of NetworkID
2021-04-15 10:01:50 +00:00
Radosław Kapka
aba2ec9aac Codecov: ignore all mock files (#8768) 2021-04-15 15:55:12 +08:00
Radosław Kapka
a8716d2949 Implement ListForkChoiceHeads in the debug API (#8675)
* initial implementation

* use ChainHeads to get heads

* API unit tests

* remove unnecessary identifier

* fix formatting

* gzl

* Update chainheads to fork choice scope

* use HeadFetcher

* fix test

* gzl

* remove junk

* remove ChainHeads from forkchoice

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-04-14 17:01:24 +00:00
Siddhant N Trivedi
04bc8a85ca Add generated file to DeepSource exclude_patterns (#8765) 2021-04-14 14:06:25 +00:00
Radosław Kapka
a9a0ecd76d Create node's Powchain registration file (#8754)
* extract powchain and remove unused function

* improve "no web3 provider" error log

* add second error log

* remove redundant code from registerPOWChainService

* remove deposit contract log from registerPOWChainService

* gzl

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-14 12:54:50 +02:00
Radosław Kapka
902e3f4f53 Fix overriding network config in tests (#8756)
* Fix overriding network config in tests

* copy config in OverrideBeaconNetworkConfig

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-14 07:39:20 +00:00
terence tsao
228033f7a3 Pass SlashValidator func as argument to ProcessProposer[Attester]Slashings (#8763)
* Pass slash validator func as argument

* Gazelle
2021-04-13 20:32:49 -05:00
Victor Farazdagi
53ffc67850 Update specs comments (#8759)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 22:26:39 +00:00
terence tsao
59eb2e60d0 Combine function parameters (#8758)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 19:56:28 +00:00
Nishant Das
0ea11ac212 Rebuild Trie After Reaching Limit (#8740)
* fix up indices

* add comment

* fix up again

* add test

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 19:12:56 +00:00
terence tsao
3e686a71e3 Move finality delay calculation (#8757)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 18:28:46 +00:00
Preston Van Loon
efbefaeb7c CI: Use experimental_remote_asset_api (#8761) 2021-04-13 17:18:47 +00:00
Nishant Das
dd7481e99c Disable Persisting Network Keys (#8735)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 16:25:35 +00:00
Preston Van Loon
fda003288d CI: minimal remote downloads, strict action environment (#8760) 2021-04-13 15:45:43 +00:00
Nishant Das
131a14ee2f Minor State Management Improvements (#8742)
* add improvement

* change to bool

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 13:23:06 +00:00
Nishant Das
45d2df1af7 Simplify Effective Balance Calculation (#8743)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 12:44:33 +00:00
Victor Farazdagi
5f3299e598 Update processJustificationAndFinalization(), per current specs (#8741) 2021-04-13 11:51:04 +00:00
Radosław Kapka
5217081567 Create node's P2P registration file (#8745)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 07:41:06 +00:00
Radosław Kapka
389bad7d24 Extract node configuration to separate file (#8744)
* Extract node configuration to separate file

* rename WarnIfNotSupported

* rename configuration to config

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 07:04:34 +00:00
Victor Farazdagi
97b4b86ddf Update NextPowerOf2() and PrevPowerOf2() funcs (#8751)
* Update NextPowerOf2() and PrevPowerOf2() funcs

* gofmt

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 06:09:56 +00:00
Victor Farazdagi
cc9bec7a19 Update specs comments (#8750)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 05:35:22 +00:00
terence tsao
8b494fb1bc ProcessRewardsAndPenaltiesPrecompute taking in rewards funcs (#8737)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 04:55:45 +00:00
Nishant Das
6aa1297829 Enable Gossip Scoring (#8730)
* enable gossip scoring

* fix some tests

* fix  up

* handle too small numbers

* add caching to validator count

* fix up

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-13 02:20:13 +00:00
Preston Van Loon
a91f2688f1 Set test timeout on //beacon-chain/rpc/validator:go_default_test. Sometimes exceeds 800s otherwise (#8752) 2021-04-13 00:24:04 +00:00
terence tsao
1c1bf37b33 Refactor EligibleForRewards into its own helper (#8739)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-12 20:26:08 +00:00
Preston Van Loon
76e36b95f7 CI: Add remote build caching support (#8748) 2021-04-12 18:46:11 +00:00
terence tsao
74cf2320ad Altair: Split no verify functions in own file (#8747)
* Split transition no verify functions in its own file

* Remove redeclared functions

* Go fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-12 16:42:08 +00:00
terence tsao
2a1c880673 Altair: Split state getters and setters into its own file (#8746)
* Categorize getters and setters into its own file

* Go fmt
2021-04-12 14:23:55 +00:00
Nishant Das
c65c6ebc38 Invert BLST Go Tag (#8725)
* invert go tag

* fix rc

* try again

* Revert "try again"

This reverts commit 70ff7658b7.

* fix fuzz

* Update shared/bls/blst/BUILD.bazel

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-04-11 11:11:15 +00:00
terence tsao
19a9b4b064 Refactor finality helpers to helpers pkg (#8734)
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-04-10 16:12:52 +00:00
Victor Farazdagi
1af88b2c35 Remove redundant MerkleRoot function (#8733)
* Remove redundant MerkleRoot function

* update merle_tree() specs comment
2021-04-10 03:13:07 +00:00
ahadda5
e3149c4f0b Slashing Protection RPC Endpoints for Web Backend (#8723)
* added the removed RPC delete account to accounts.go  and the rpc in proto

* reverted the 3 unit tests namely the failed derived delete, no pub keys provided and the successful imported account with provided public keys; also  brought back the createImportedWalletWithAccounts back in wallet_test.go

* strong password defined elsewhere- removed

* Update validator/rpc/accounts_test.go

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

* added PublicKeys Nil test case

* changed ss to s. ss was a bad name inthe first place

* goimports -w root

* fixed the goimports before running the proto scripts, also changed the deleterequest variable to PublicKeysToDelete

* removed unneeded comment

* added test case for derived, changed delete account to be for both imported and derived

* gofmt

* unrelated files

* unrelated files

* unrelatedfiles restored

* revert unrelated files

* changed the last ss

* adding slashign endpoints

* adding the rpc export and import funcs, still need more testing and add unit tests

* added import slashing unit test

* clean up

* remove less

* Update proto/validator/accounts/v2/web_api.proto

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update proto/validator/accounts/v2/web_api.proto

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update proto/validator/accounts/v2/web_api.proto

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update proto/validator/accounts/v2/web_api.proto

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* camelCase Proto

* update slashing_protection_json

* update proto

* register in validator/rpc/gateway

* removed the server db creation, the validator cannot begin with a null db

* round trip test

* gofmt

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-04-09 19:13:59 +00:00
Victor Farazdagi
0808c02c65 Update spec comments (#8727) 2021-04-08 19:33:54 +00:00
Victor Farazdagi
76390c94af Refactor ProcessFinalUpdates(), per updated specs (#8724) 2021-04-08 14:20:52 +00:00
Nishant Das
f0e2f561d5 Make BLST The Permanent Default (#8710)
* remove herumi

* gaz

* deprecate flag

* remove source builds of herumi

* remove

* Revert "remove source builds of herumi"

This reverts commit ac7dd133ed.

* disable blst

* remove herumi hard requirement from fuzz

* restrict viz, ensure all deps removed from fuzz

* remove source builds

* add back opts

* add back herumi initialization

* Revert "add back opts"

This reverts commit ad9b409b8a.

* Revert "remove source builds"

This reverts commit b78ee30dba.

* Revert "restrict viz, ensure all deps removed from fuzz"

This reverts commit 65d951da93.

* Revert "remove herumi hard requirement from fuzz"

This reverts commit ad92191d81.

* redundant

* add lock for rand generation

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-04-07 10:18:19 -05:00
Victor Farazdagi
74d0134ee3 Weak subjectivity minor refactoring (#8715)
* Add IsWithinWeakSubjectivityPeriod helper method

* Add LatestWeakSubjectivityEpoch method

* ParseWeakSubjectivityInputString helper

* switch to Checkpoint

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-06 14:32:49 +00:00
Victor Farazdagi
91df0112c7 Add LatestWeakSubjectivityEpoch() method (#8707)
* Add IsWithinWeakSubjectivityPeriod helper method

* Add LatestWeakSubjectivityEpoch method

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-06 09:08:44 +03:00
terence tsao
7998348bcb Fix deep source complains (#8714) 2021-04-05 23:04:26 +00:00
ahadda5
99bd988375 Web Backend Recover Wallet (#8679)
* recover wallet rpc support - first attempt

* removed redundant check

* separate createwallet into imported and derived. Recover is derived

* added unit test for recover. Recover is the createWallet for derived

* so proto does CamelCase!

* fixed issues related to unit testing

* expose ValidateMnemonic from accounts to be used by the rpc module

* added Mnemonic25Support and test to ensure it is not et is not empty

* added skipMnemonic25thword support and unit test

* Update proto/validator/accounts/v2/web_api.proto

Proper naming convention

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* ran goimports,changed variable to SkipMnemonic_25ThWord

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update validator/rpc/wallet.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* fixed variable and text msgs naming convention as per the review

* added unit test for strong password on recover

* Update proto/validator/accounts/v2/web_api.proto

Co-authored-by: Nishant Das <nish1993@hotmail.com>

* Update validator/rpc/wallet.go

Co-authored-by: Nishant Das <nish1993@hotmail.com>

* goimports -w on root proto

* added comments after exposing ValidateMnemonic to by used by rpc.RecoverWallet

* language should be case insensitive

* need to goimports before update protobuf scripts

* Update validator/rpc/wallet.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/rpc/wallet.go

comments need to be consistant

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/rpc/wallet_test.go

consistent comments

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* fix comments

* remove the skipMnemonic from rpc, just check if passphrase is empyt

* defer call to set the writePassword flag on web boarding

* gofmt

* fixed the password write test after recovering a wallet. Needed to have two defers. One to set to true then one back to false

* restore powchain.pb.go and finalized_block_root_container.pb.go

* revert beacon messages.pb.go

* revert unrelated files

* revert unrelated files

* revert unrelated files

* unlreated files

* restored the imports

* Update validator/rpc/wallet_test.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Nishant Das <nish1993@hotmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-05 20:42:03 +00:00
Raul Jordan
0a2f3e4d48 Resolve Misc DeepSource Lint Issues (#8711) 2021-04-05 19:37:25 +00:00
Victor Farazdagi
dfe5372db5 Add IsWithinWeakSubjectivityPeriod helper method (#8706)
* Add IsWithinWeakSubjectivityPeriod helper method

* Nishant's suggestion on cache reset

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-05 18:26:31 +00:00
terence tsao
f2f509be0e Block deposit: refactor batch verify and validation activation (#8698)
* Block deposit: refactor batch verify and validation activation

* Return beacon state

* Return nil

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-05 16:49:17 +00:00
terence tsao
01eb77c834 ProcessPreGenesisDeposits: Remove context.TODO() usage (#8705)
* ProcessPreGenesisDeposits: Remove context.TODO() usage

* apply #8704 change

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-05 15:07:56 +00:00
Nishant Das
3cd95b4a6c copy better (#8708) 2021-04-05 08:48:19 -05:00
Preston Van Loon
80ab9201b3 Update blst (#8703)
* Update blst to v0.3.4

* go mod tidy

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-04-04 19:59:32 +08:00
terence tsao
1c6c058bba Genesis beacon state: refactor update eth1 data (#8704) 2021-04-03 23:19:48 +02:00
terence tsao
528cd89616 Move chainheads to blockchain pkg (#8700)
* Move chainheads to block chain's head info

* Fix mock
2021-04-03 11:25:25 +00:00
Preston Van Loon
c179cfb93e BLS: Deprecate usage of AggregateVerify (#8699)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-04-02 15:53:08 +00:00
terence tsao
f67228bacb Change ProcessDeposits argument to use deposits (#8696) 2021-04-02 14:48:41 +00:00
Nishant Das
af3d3e8cd3 Update Gossip Parameters (#8683)
* add in more accurate aggregate parameters

* add more param changes

* more cleanup

* fix order of operations

* comments

* remove redundant declaration

* clean up better

* fix up

* victor's review

* disable mesh scoring

* disable mesh scoring

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-04-02 20:21:19 +08:00
ahadda5
878439065c Web Backend Revert delete rpc (#8681)
* added the removed RPC delete account to accounts.go  and the rpc in proto

* reverted the 3 unit tests namely the failed derived delete, no pub keys provided and the successful imported account with provided public keys; also  brought back the createImportedWalletWithAccounts back in wallet_test.go

* strong password defined elsewhere- removed

* Update validator/rpc/accounts_test.go

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

* added PublicKeys Nil test case

* changed ss to s. ss was a bad name inthe first place

* goimports -w root

* fixed the goimports before running the proto scripts, also changed the deleterequest variable to PublicKeysToDelete

* removed unneeded comment

* added test case for derived, changed delete account to be for both imported and derived

* gofmt

* unrelated files

* unrelated files

* unrelatedfiles restored

* revert unrelated files

* changed the last ss

* restore imports

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-04-02 11:33:42 +02:00
Victor Farazdagi
acf17f9b82 Weak subjectivity period calculating helper (#8695)
* move helpers to their own file

* implement ComputeWeakSubjectivityCheckptEpoch

* remove helper func

* fix unit tests

* rename
2021-04-01 22:50:04 +00:00
Victor Farazdagi
9afa304817 Skip e2e test for previous implementation of slasher (#8693) 2021-03-31 17:22:23 +00:00
Radosław Kapka
847640333a Wrap long lines in validator package (#8691) 2021-03-31 14:32:35 +00:00
Preston Van Loon
28e4a3b7e8 Add a Tool to Split a Series of Mnemonic Keys into Distinct Wallets (#8651)
* Add a tool to split a series of mnemonic keys into distinct wallets

* split func

* keysplit tool

* gaz/viz

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-30 20:38:40 +00:00
Raul Jordan
d7103fdef3 HTTP Request Sink Tool (#8689)
* request sink test

* append if not exist
2021-03-30 16:42:50 +00:00
Radosław Kapka
f822f0436e Break long lines in beacon chain package (#8686)
* Break long lines in beacon chain package

* change log formatting

* Revert "change log formatting"

This reverts commit b610fd67ed.

* Revert "Break long lines in beacon chain package"

This reverts commit 53215fdcde.

* wrap lines over 160

* revert go.mod and go.sum
2021-03-30 11:24:46 +00:00
Potuz
0b06c48ed0 Fix typo in comment for LoadGenesis (#8685) 2021-03-30 00:45:14 +00:00
Radosław Kapka
190d862552 Implement GetBeaconState in the debug API (#8631)
* Return status.Errorf instead of plain errors from gRPC functions

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

* extracted StateFetcher

* StateFetcher tests

* extract beacon state creation option and fix state tests

* add comment to StateFetcher

* register the server

* implement grpc function

* test ToProto

* gRPC function test with mock state fetcher

* reduce visibility of packages

* add missing error assertion

* removed unused code

* overwrite config name

* gzl

* Fix service fields

* rename StateFetcher to Provider

* Update beacon-chain/state/stateV0/state_trie.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* adjust code to new v0 interfaces

* interface/struct naming changes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-29 21:04:35 +00:00
terence tsao
a8ab279cb8 Protoarray: add ChainHeads (#8684)
* Add ChainHeads

* Add only has bestChild case

* Update beacon-chain/forkchoice/protoarray/store.go

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-29 17:40:38 +00:00
Victor Farazdagi
feeb59de23 Add a separate unit test for ComputeDomainAndSign (#8600)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-29 15:26:50 +00:00
terence tsao
2ec3f79146 Remove unused interface (#8682) 2021-03-28 22:53:34 +02:00
Victor Farazdagi
e26dab84f6 E2E remove redundant test case (#8680) 2021-03-28 15:19:51 +00:00
Nishant Das
4886a4e749 Add Remaining Gossip Scoring Topics (#8678)
* add for topics

* Apply suggestions from code review

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-03-28 09:37:25 +08:00
Victor Farazdagi
54cf5f3c7a Add connectivity E2E test (#8607)
* Add connectivity e2e test

* randomized backoff period on discovery

* fix signature

* gazelle

* deterministic randg

* define ComponentRunner

* update ETH1 node

* extrace BootNode

* add logger

* remove refs to t

* gazelle

* update BeaconNode

* parametrize tests

* update log formatting

* update ValidatorNode

* remove redundant test id from params

* decrease delta

* move BootNode

* update BootNode

* revert params

* update SlasherNode

* mask unused param

* update helpers

* update test runner

* go mod tidy

* remove unused fields

* re-arrange tests

* extract sync into its own method

* gazelle

* BeaconNode

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

* remove deprecated method

* BeaconNodes -> BeaconNodeSet

* make sure that slasher is required component

* update StartBeaconNodeSet() and StartValidatorNodeSet()

* update SlasherNodeSet

* gazelle

* update connectivity tests

* Nishant's suggestion

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-27 00:33:50 +00:00
terence tsao
5f2f53a0a6 Harden beacon state interface for Altair (#8673)
* State: clean up

* Add error to return signature

* Remove SetCurrentEpochAttestations and SetPreviousEpochAttestations

* Fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-26 18:15:03 +00:00
Nishant Das
7f0c92504f Add DB To P2P Service (#8676)
* add files

* goimports
2021-03-26 09:51:58 -05:00
Victor Farazdagi
961a012502 E2E refactoring (#8643)
* define ComponentRunner

* update ETH1 node

* extrace BootNode

* add logger

* remove refs to t

* gazelle

* update BeaconNode

* parametrize tests

* update log formatting

* update ValidatorNode

* remove redundant test id from params

* decrease delta

* move BootNode

* update BootNode

* revert params

* update SlasherNode

* mask unused param

* update helpers

* update test runner

* go mod tidy

* remove unused fields

* re-arrange tests

* extract sync into its own method

* gazelle

* BeaconNode

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

* remove deprecated method

* BeaconNodes -> BeaconNodeSet

* make sure that slasher is required component

* update StartBeaconNodeSet() and StartValidatorNodeSet()

* update SlasherNodeSet

* gazelle
2021-03-25 22:15:58 -05:00
Victor Farazdagi
139017546d E2E refactoring: SlasherNodeSet and SlasherNode (#8672)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-26 01:22:32 +00:00
Preston Van Loon
5d12cc1ded Add beaconState RotateAttestations API method (#8669)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-25 22:05:15 +00:00
Preston Van Loon
e32c88e14c Update github.com/dgraph-io/ristretto (#8671) 2021-03-25 19:52:16 +00:00
Victor Farazdagi
6a4d4d7028 E2E refactoring: BeaconNode and BeaconNodeSet (#8667)
* E2E refactoring: BeaconNode and BeaconNodeSet

* unstuck!

* hope the magic has worked!
2021-03-25 17:48:09 +03:00
Victor Farazdagi
e56ab297b1 E2E refactoring: ValidatorNode and ValidatorNodes (#8665)
* E2E refactoring: ValidatorNode and ValidatorNodes

* add deprecation warning

* Radek's suggestion on naming

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-25 10:35:06 +00:00
Victor Farazdagi
ad303fb943 E2E refactoring: ETH1 Node (#8663)
* Eth1Node added

* gofmt

* update types

* update types

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-25 00:16:11 +00:00
Victor Farazdagi
89da5d1ef5 E2E refactoring: bootnode (#8659)
* BeaconNode

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 20:55:12 +00:00
Raul Jordan
82f25bacf2 Fix All Deep Source Shell Issues and Go Issues (#8661)
* most issues resolved

* fuzz wrapper fixes

* more deepsource

* more shell

* export

* shell

* combine func params, fix go deep source issues

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 19:57:27 +00:00
Raul Jordan
b2d9f9a2d8 Fix Secrets Failing Build (#8660)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 18:01:58 +00:00
Potuz
9cb4eafad4 Change early exit error message (#8657)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-24 11:17:52 -05:00
Potuz
ff40a68215 Add prater exit info (#8656)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-24 13:50:06 +00:00
Radosław Kapka
2fe50c5edd Rename state_fetcher.go (#8646)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 09:08:39 +00:00
Radosław Kapka
3e92ae0f48 Use context timeout during gateway service shutdown (#8644)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 05:00:47 +00:00
Radosław Kapka
c112d27ab5 Extract filling testutil's beacon chain root (#8645)
* Extract filling testutil's beacon chain root

* gzl

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-24 03:47:36 +00:00
terence tsao
a539e3d66e Move handleValidatorSlice and handleByteArrays to stateutil pkg (#8653)
* State: clean up

* Share handleArray and handleValdiator root functions
2021-03-24 01:59:23 +00:00
terence tsao
446029c1ba State: rename a few things (#8650)
* State: clean up

* Rename to Uint64ListRootWithRegistryLimit

* Gazelle
2021-03-23 21:17:09 +00:00
Nishant Das
fba56df765 Fix Powchain Genesis (#8647)
* fix powchain genesis

* Setup test with a deposit cache

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-03-23 16:44:57 +00:00
Radosław Kapka
8281634131 Introduce API StateFetcher (#8639)
* Return status.Errorf instead of plain errors from gRPC functions

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

* extracted StateFetcher

* StateFetcher tests

* extract beacon state creation option and fix state tests

* add comment to StateFetcher

* remove empty line

* overwrite config name

* fix field names

* remove FillRootsNaturalOpt helper

* reduce statefetcher package visibility

* gzl

* add missing error assertion

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-22 15:19:38 +00:00
Nishant Das
b346cde919 fix deduplication (#8640) 2021-03-22 07:07:58 -07:00
kevlu93
eca67cec4c Embed Config Pattern for Sync Services (#8636)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-21 19:07:42 +00:00
kevlu93
14439d2b12 Embed Config Pattern For Slasher, Slashing Protection (#8637)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-21 17:53:17 +00:00
kevlu93
4a64d4d133 Embed Config Pattern For Attestation, POW Chain, and RPC Services (#8635) 2021-03-21 16:58:41 +00:00
terence tsao
9421ac13d8 State: various clean up (#8633)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-19 20:03:19 +00:00
Raul Jordan
d2b1115f46 Feature Flag for Enabling Slashing Protection Pruning (#8632) 2021-03-19 17:54:47 +00:00
Preston Van Loon
9282a73663 Revert "Ignore Syncing Freelist For Validator DB" (#8629)
This reverts commit 3b6b3f6ef6.

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-03-19 05:30:09 +00:00
terence tsao
799a4d80cd State: refactor common root functions (#8630) 2021-03-18 16:29:06 -07:00
Preston Van Loon
fe6e6909e6 Validator Attestation History Pruning: Use a bolt cursor instead of bucket.ForEach, exit early when applicable (#8627)
* Use a bolt cursor instead of bucket.ForEach, exit early when applicable

* Refactor to reuse the same code

* gofmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-18 22:39:28 +00:00
Preston Van Loon
e477fdfd6d Embedded mainnet genesis state + load genesis.ssz from file (#8614)
* Update rules_go and fix proto conflicts

* gaz

* Update generated code

* First pass inclusion of using baked states

* more emptypb fixes

* remove testnet genesis files, only embed mainnet

* Refactoring for SaveGenesisData, fix tests that use mainnet config but do not support mainnet genesis values

* a bit more refactoring, load genesis from a file. Needs tests still

* Add method to ensure an embedded genesis file also has the appropriate genesis block

* gofmt

* more clear error

* Check genesis fork version to ensure testnet config matches genesis file

* viz

* test for SaveGenesisData

* More genesis db method tests

* Merge

* Minor tweaks, lint, fmt, etc

* Add more test to genesis db methods

* Revert beacon-chain/state/stateV0/BUILD.bazel

* Update beacon-chain/db/iface/errors.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* PR feedback

* Update beacon-chain/db/kv/genesis.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* fmt.Errorf works better for nil errors

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-18 21:00:00 +00:00
terence tsao
a921455836 Remove no bootnode error for Prater (#8628) 2021-03-18 19:38:04 +00:00
terence tsao
beadec32b8 Add prater boot nodes (#8623)
* Add bootnodes

* Typos

* Add sigp's lighthouse node
2021-03-18 14:26:18 +00:00
Nishant Das
693ce7b952 Mask All Debug Logs for Endpoints (#8624) 2021-03-18 09:13:01 +00:00
terence tsao
ce725ceec3 Move state pkg to stateV0 pkg (#8620)
* Move state pkg to stateV0 pkg

* Build.bazel

* Remove unused RootsArrayHashTreeRoot

* Revert "Remove unused RootsArrayHashTreeRoot"

This reverts commit bf0bda30d1.

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-17 19:49:49 +00:00
kevlu93
ecf25d1284 Embed Config Pattern For Blockchain Service and Update Dependency Names Accordingly (#8618)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-17 13:36:56 -05:00
Radosław Kapka
0a73be7389 Return status.Errorf instead of plain errors from gRPC functions (#8619)
* Return status.Errorf instead of plain errors from gRPC functions

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-17 16:47:44 +00:00
Preston Van Loon
034a28710e Add Prater config (#8613)
* Add Prater config

* Register flag everywhere

* gofmt

* Apply suggestions from code review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Update shared/params/testnet_prater_config.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-17 14:14:07 +00:00
terence tsao
7b16601399 State: Return interface{} for pb related methods (#8617)
* Return interface{} instead of *pbp2p.BeaconState

* Comment
2021-03-16 22:26:17 -05:00
terence tsao
50e99fb6c1 State: Move compute field roots functions next to implementation (#8615) 2021-03-16 11:14:26 -07:00
terence tsao
ea4ea3d1c1 Remove unused AttestationDataRoot (#8610)
* Remove unused AttestationDataRoot

* Gazelle

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-16 16:12:32 +00:00
Radosław Kapka
1f8171d069 Dynamic key reload for remote keymanager (#8611)
* Dynamic key reload for remote keymanager

* fix failing keymanager test

* keymanager tests

* define RemoteKeymanager interface

* WaitForActivation tests

* gzl

* handle error in test
2021-03-16 10:00:05 -05:00
terence tsao
9fea9816bd BeaconState: Expose MarshalSSZ (#8609) 2021-03-16 00:43:27 +00:00
terence tsao
aa389c82a1 Send attestations over feed at right place (#8605) 2021-03-15 07:47:10 -07:00
Radosław Kapka
c577fbd772 Move attestation's source checkpoint validation to VerifyAttestationNoVerifySignature (#8598)
* Move attestation's source checkpoint validation to VerifyAttestationNoVerifySignature

* change parameter type to ReadOnlyBeaconState

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-03-12 21:43:20 +00:00
Radosław Kapka
dc6dee3f4e Fix issues with dynamic key reload for imported/derived keymanager (#8585)
* implementation of handling reload

* proper implementation

* fix WaitForActivation tests

* HandleKeyReload tests

* runner tests

* do not reuse log hook between tests

* gzl

* Drop unnecessary use of the blank identifier

* move mock_validator to testutil package

* Reorganize validator client package

* reduce package visibility

* revert account changes

* gzl

* describe nil parameter

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-12 17:23:56 +00:00
Nishant Das
a3c96c2f44 Prune Better For Larger Buckets (#8599)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-12 15:05:20 +00:00
Nishant Das
3b6b3f6ef6 ignore syncing freelist for validator db (#8601) 2021-03-12 08:06:20 -06:00
Preston Van Loon
eb694ab5d5 Update rules_go and fix proto conflicts (#8596)
* Update rules_go and fix proto conflicts

* gaz

* Update generated code

* more emptypb fixes

* gaz

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-03-11 18:03:19 -06:00
Victor Farazdagi
fa2084330b Fix race condition in TestService_Initialized (#8597) 2021-03-11 21:16:40 +00:00
Raul Jordan
286444a2ec Shorter Pruning Period for Slashing Protection (#8590)
* begin a simpler pruning process

* shorter pruning

* pass all pruning tests

* passing tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-11 15:51:16 +00:00
Victor Farazdagi
55b6134be1 Improves UTs coverage in shared/aggregation (#8593)
* improves shared/aggregation test suite

* improves coverage in shared/aggregation/attestations
2021-03-11 15:01:19 +00:00
Radosław Kapka
5374d07c4d Reorganize validator client package (#8592)
* Reorganize validator client package

* reduce package visibility
2021-03-11 11:57:41 +00:00
terence tsao
b62619ae3a State: Refactor Reference and ValidatorMapHandler to stateutil pkg (#8589)
* Starting

* Fix tests

* Gazelle
2021-03-10 20:57:46 -06:00
terence tsao
dc0fc94c13 Use read lock (#8588) 2021-03-10 15:11:25 -08:00
Victor Farazdagi
548b471b8a Simplify nil assignments (#8587)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-10 20:38:16 +00:00
Victor Farazdagi
fa92766095 Fixes flaky TestBlocksFetcher_nonSkippedSlotAfter test (#8586)
* Fixes flaky TestBlocksFetcher_nonSkippedSlotAfter test

* fix conditional
2021-03-10 20:03:26 +00:00
Benoit Perroud
9980ca3b7e Add metrics per keys for next scheduled attestation and proposal (#8583)
* Add metrics per keys for next scheduled attestation and proposal

* Found a better place where to update the counters

* Wrap with emitAccountMetrics flag
2021-03-09 21:13:11 +00:00
terence tsao
72be10f9a5 Ran go imports (#8582) 2021-03-09 19:56:05 +00:00
Raul Jordan
ab301aa4fe Remove Accounts Enable/Disable Code (#8576)
* rem

* remove all enable disable code

* fix broken build

* fix more tests

* fix broken tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-09 15:46:50 +00:00
Nishant Das
2bb0a602e4 create the bucket only once (#8579)
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-03-09 08:22:52 -06:00
Nishant Das
363771a5c7 Update Go Mod (#8578) 2021-03-09 10:26:06 +00:00
terence tsao
bdf2b2019b Use beacon state interfaces across (#8552) 2021-03-08 14:37:33 -08:00
Victor Farazdagi
f2125e5f64 Proposer attestation selection using max-cover (#8571)
* Proposer attestation selection using max-cover

* better alisgn struct field

* more tests

* cleanup

* simplify expressions

* add benchmarks

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-08 18:46:24 +00:00
Victor Farazdagi
294b031fa4 Fixes incorrect usages of gazelle:ignore (#8562)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-08 18:09:39 +00:00
Raul Jordan
4a98300c59 Use Path to Deposit Data JSON File in Generate Genesis State (#8575)
* use path to deposit data json

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-08 16:57:30 +00:00
Preston Van Loon
0f1d14437c Update blst to v0.3.3 (#8574)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-08 15:40:10 +00:00
Radosław Kapka
79754bded2 Implement SubmitAttestations in the beacon API (#8563)
* update ethereumapis deps

* V1AttToV1Alpha1 migration

* Implementation plus happy path test

* fix root variable names

* Invalid attestation test

* gzl

* mod tidy

* use a single append to concatenate two slices

* remove outdated comment from attestation processing

* invoke ProcessAttestationNoVerifySignature when validating attestations

* implement missing PoolMock members

* use new VerifyAttestationNoVerifySignature function
2021-03-08 15:42:05 +01:00
terence tsao
90da16432f Refactor ProcessAttestationNoVerifySignature to VerifyAttestationNoVerifySignature (#8566)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-06 14:53:28 +00:00
Preston Van Loon
f074c5ee89 Fix validator activation monitoring with inactive keys (#8558)
* refactor / move waiting for activation updates

* Commentary

* Update test to follow the full code path

* gofmt and goimports

* manual imports fixes

* Apply suggestions from code review

typo fixes

* Remove redundant handleAccountsChanged and chan. Thanks @nisdas

* var sub = to sub :=

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-03-05 18:33:39 +00:00
Radosław Kapka
edd86fd358 Simplify API beacon pool tests (#8564)
* fix comment of FarFutureEpoch

* remove not needed validator configuration
2021-03-05 16:10:48 +00:00
Nishant Das
067a519b37 Add Spans To Attestation Caches (#8556)
* add spans

* preston's comments

* add span
2021-03-05 09:17:27 -06:00
Raul Jordan
32f2f711db Exclude Instead of Ignore With Gazelle (#8559)
* exclude and not ignore

* fix broken test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-04 21:01:32 +00:00
terence tsao
c1d4ff6239 Use deep ssz (#8557) 2021-03-04 13:31:39 -06:00
Radosław Kapka
e36c3dd668 Ignore "safe" secrets in DeepsSource analysis (#8555) 2021-03-04 13:52:55 +00:00
terence tsao
1c7c62cf8a Attestation pool: continue if bad (#8550)
* Continue saving attestation when one is bad

* Gazelle

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-04 08:14:47 +00:00
Raul Jordan
d215607e55 Add Goland Standard "cmd" Pattern for Slasher Binaries (#8542)
* vis

* gaz

* imports

* slasher img

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-03-03 18:37:57 +00:00
Raul Jordan
ff329df808 Add All Other Prysm CLI Entrypoints to "cmd" Folder (#8545)
* other cmd

* comments

* gaz

* gaz ignored file

* build

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-03 17:05:37 +00:00
Preston Van Loon
c9858b5e6b Validator: Remove optional and duplicated dial opts for streaming middleware (#8549) 2021-03-03 10:28:13 -06:00
Nishant Das
565d51009d Make DB Backup More Efficient (#8543)
* checkpoint

* add test

* Update beacon-chain/db/kv/backup_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-03 15:37:13 +00:00
terence tsao
c6b74b2ba7 Beacon state: Add interfaces (#8544)
* Define Readonly and writeonly

* Comment

* First take at clean up

* Completed interfaces

* Fix build and test

* Reordering interfaces

* Add build.bazel

* Add build.bazel

* Fix visibility
2021-03-03 02:26:24 +00:00
Raul Jordan
090fbbf18c Add Goland Standard "cmd" Pattern for Beacon-Chain Binaries (#8540)
* beacon chain cmd pattern

* imports spacing

* more import fix

* edit build file

* e2e viz

* amend e2e
2021-03-02 13:36:03 -06:00
Raul Jordan
cdea2debc9 Add Goland Standard "cmd" Pattern for Validator Binaries (#8541)
* validator cmd

* imports

* more imports

* e2e viz

* alias

* use native alias

* add actual

* fix macro

* work on fix e2e

* add viz

* gaz

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-03-02 12:58:40 -06:00
terence tsao
4c49d4af7e Clean up state pkg's getter and setter (#8533)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-02 12:37:36 +00:00
Panagiotis Georgiadis
46f6bd6d08 A bit of cleanup based on goconst tool (#8529)
* Make 1 occurence of 'foo', 'bar' and 'fizz!'

* Make 1 occurence of 'merkleizing list that is too large, over limit' string

* Limit password occurrences

* Make only 1 occurence of 'strongPass'

* Limit testMnemonic occurrences

* Limit expected epoch error messages

* Rename errors and use constant

* Update bazel dependencies

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-03-02 11:39:54 +00:00
Preston Van Loon
b3dcbfe2a4 Update snappy to fix ARM64 with go.1.16 (Reverts #8538) (#8539)
* Revert "Revert "Update to go 1.16" (#8538)"

This reverts commit a92b20d2bb.

* Update snappy
2021-03-02 16:54:16 +08:00
Nishant Das
a92b20d2bb Revert "Update to go 1.16" (#8538)
This reverts commit f4adc0ea86.
2021-03-02 05:35:08 +00:00
Nishant Das
8a27449595 Increase default peer limit from 30 to 45 (#8530)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-01 18:35:27 +00:00
Eduard Klementiev
a3781e2ffc Add prysm version to prometheus (#8527)
* Add prysm version to prometheus

* gofmt

* apply suggestion

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-03-01 17:50:20 +00:00
Radosław Kapka
f973924fbf Implement SubmitVoluntaryExit and SubmitProposerSlashing in the beacon API (#8532)
* SubmitProposerSlashing

* SubmitVoluntaryExit

* rename variables
2021-03-01 16:08:39 +00:00
Radosław Kapka
9547f53e88 Migration package tests (#8524)
* first few tests

* rest of tests

* gzl

* test block hydration

* compare roots

* gzl

* compare exit roots

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-03-01 13:52:07 +00:00
terence tsao
c30ee6c166 Ran go import (#8528)
* Ran go import

* Sort
2021-02-28 13:49:00 +01:00
ahadda5
29d1959b81 Recursively Find Validator Database File In Slashing Protection Commands (#8518)
* issue/feature 8500 find validator.db automatically

* gazelle build

* remove less! why there?

* fixed errors import

* fixed errors import

* unit tested

* adding the find validator.db fileutil func to export and import slashing

* deleted the comment

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-26 11:04:18 -06:00
Eduard Klementiev
878bc15229 Add --list-validator-indices flag (#8520)
* Add --list-validator-indices flag

* Fix style issues

* Print pubkeys alongside the validator indexes

* Improve list-indices output

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-02-26 15:00:05 +00:00
Nishant Das
e39ce36f1c Fix Default Transport Option (#8525)
* fix

* mod
2021-02-26 10:26:39 +01:00
Nishant Das
b4648f1df9 Update Test Case in Batching Public Keys (#8523) 2021-02-26 01:44:42 +00:00
Preston Van Loon
f4adc0ea86 Update to go 1.16 (#8521)
* Update to go 1.16

* Also update go.mod

* rm go.sum then run go mod tidy

* go mod tidy with go 1.16

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-25 21:38:19 +00:00
terence tsao
658cbf5631 RPC: Proper status code for error (#8519)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-25 20:00:33 +00:00
terence tsao
b400098296 Remove unused code (#8517)
* Remove unused code

* Go mod tidy

* Gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-25 18:13:13 +00:00
Radosław Kapka
c3f875bf65 Implement SubmitAttesterSlashing in the beacon API (#8515)
* Implement SubmitAttesterSlashing in the beacon API

* gzl

* remove migration test rule

* fix BUILD file formatting

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-25 11:14:04 -06:00
pinglamb
5db5ca7056 Use eth2-types SSZUint64 (#8514) 2021-02-25 05:51:26 -08:00
Josh Yudaken
f0eb843138 Graffiti ordered index (#8482)
* Added ordered option to graffiti file

* Updated validator to use Ordered graffiti

* Track graffiti ordered index in db

* Update `ordered` to only emit each graffiti once

Co-authored-by: pinglamb <pinglambs@gmail.com>
2021-02-24 22:50:47 +00:00
Potuz
d44c27ec63 Log block arrival time (#8485)
* Log block arrival time

* Comment formatting

* Update beacon-chain/sync/validate_beacon_blocks.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-02-24 20:35:19 +00:00
Nishant Das
0625a6906c Add Better Peer Pruning (#8501)
* add better pruning

* add test

* gaz

* victor's review

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-24 18:40:06 +00:00
Radosław Kapka
4d28d5e4d2 Listen for account changes only when required (#8503)
* initial implementation

* remove listening for changes from wallet creation

* goimports

* test fix

* more goimports

* listen for changes when initializing wallet through gRPC

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-24 18:05:46 +00:00
Nishant Das
08b938982b Propagate Cancellation To Beacon Node Server (#8512)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-24 17:10:25 +00:00
Raul Jordan
6ee290a9af Analyze Secret Credential Additions in DeepSource (#8511)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-24 16:21:28 +00:00
Radosław Kapka
4da7a7797e Implement ListPoolProposerSlashings and ListPoolVoluntaryExits in the beacon API (#8508)
* Implement ListPoolProposerSlashings in the beacon API

* implement ListPoolAttesterSlashings

* add comments to bool arguments

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-24 15:29:25 +00:00
Preston Van Loon
6e831920bf Fix slice out of bounds error in validator db migration (#8510)
* Fix slice out of bounds error in validator db migration #8509

* Add regression testing

* make it double just in case

* gofmt
2021-02-24 15:02:39 +00:00
terence tsao
eca8d85446 Remove outdated and skipped TestConsistentGenesisState (#8506)
* Rm skipped TestConsistentGenesisState

* Fix build: remove unused imports

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-02-24 13:40:19 +00:00
terence tsao
1db3c86b68 Use DeepSSZEqual to satisfy go tests (#8499)
* Use DeepSSZEqual to satisfy go tests

* New line

* New line

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-23 22:20:11 +00:00
Raul Jordan
0c599521b1 Better Handling of Subscriber Errors in Logs Streams (#8505)
* handle subscriber error and increase buffer sizes

* operation order in unsub and close
2021-02-23 15:33:23 -06:00
Radosław Kapka
e40fba7679 Implement ListPoolAttesterSlashings in the beacon API (#8492)
* pool interface and mock

* implementation

* gofmt

* gzl

* Use migration package for slashing mapping

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-23 16:17:07 +01:00
terence tsao
6b82873737 Use validatorIndex instead of validatorID (#8498)
* Use ValidtorIndex across Prysm. Build ok

* First take at fixing tests

* Clean up e2e, fuzz... etc

* Fix new lines

* Update beacon-chain/cache/proposer_indices_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update beacon-chain/core/helpers/rewards_penalties.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update beacon-chain/core/helpers/shuffle.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/graffiti/parse_graffiti_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Raul's feedback

* Fix downcast int -> uint64

* Victor's feedback

* Replace validator id with validator index

* Replace validator id with validator index

* Typo

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-22 19:40:58 -06:00
terence tsao
3edfa8cb88 Use Custom Type ValidatorIndex Across Prysm (#8478)
* Use ValidtorIndex across Prysm. Build ok

* First take at fixing tests

* Clean up e2e, fuzz... etc

* Fix new lines

* Update beacon-chain/cache/proposer_indices_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update beacon-chain/core/helpers/rewards_penalties.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update beacon-chain/core/helpers/shuffle.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/graffiti/parse_graffiti_test.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Raul's feedback

* Fix downcast int -> uint64

* Victor's feedback

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-23 00:14:50 +00:00
Victor Farazdagi
b577869ed6 Fixes import aliases (#8497)
* Fixes import aliases

* another fix

* reset gw files

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-22 23:20:57 +00:00
Ivan Martinez
5c14b4c833 ETH2 API: Add outline for debug endpoints (#8496)
* Add outline for debug endpoints

* Add outline for debug endpoints

* Fix comment

* Fix visibility
2021-02-22 16:48:49 -06:00
Potuz
dd08305aa7 Clean duplicated topic field in debug log (#8489)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-22 18:13:26 +00:00
Victor Farazdagi
1395c11c29 Fix duplicate import (#8494) 2021-02-22 17:36:18 +00:00
Potuz
ef48f6a061 Move timings of synced block to debug level (#8491)
* Move timings of synced block to debug level

* go fmt

* Change message text

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-22 16:32:23 +00:00
terence tsao
09ddfae1d9 Use DeepSSZEqual for tests (#8484)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-22 15:33:55 +00:00
Preston Van Loon
ad9cd1933a Add nil check for validator db migration (#8493)
* Add nil check for validator db migration

* continue if source bucket is nil
2021-02-22 14:28:34 +00:00
Nishant Das
0f515784d8 Update Geth Fork (#8490)
* update to latest

* fix
2021-02-22 21:35:45 +08:00
Radosław Kapka
7d3e53f3e4 Constrain read/write channels (#8479) 2021-02-19 15:39:27 +00:00
terence tsao
dc1bec79ed Use Eth2 type CommitteeIndex (#8477)
* Use types.CommitteeIndex

* Go fmt

* Update validator pkg

* Fix e2e

* Happy fuzz tests

* Sync with upstream ethereumapi

* Go mod tidy

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-18 20:11:20 +00:00
terence tsao
d472380fef Hide beacon operation field in log if it's 0 (#8330)
* Hide beacon operation field if it's 0

* Update test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-18 19:08:27 +00:00
terence tsao
eea0160dd4 Reformat healthz message by adding a comma (#8472)
* Add comma

* Update shared/prometheus/service.go

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

* Update tests

* Apply suggestions from code review

* Update shared/prometheus/service_test.go

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-18 16:31:16 +00:00
Radosław Kapka
1ae429dc61 Implement GetFinalityCheckpoints in the beacon API (#8476)
* span

* Implement GetFinalityCheckpoints in the beacon API
2021-02-18 09:46:17 -06:00
pinglamb
fc265055df Update bazelbuild/rules_go to 0.24.13 (#8463)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-02-18 12:57:16 +08:00
Nishant Das
917252d7d0 Use Correct Peer Status Method (#8471) 2021-02-18 03:35:44 +00:00
Raul Jordan
4f9752bb3e Stop Early in Validator Surround Vote Local Protection (#8460)
* include migration and logic for stopping early in slashing protection checks

* remove commented code

* extract methods

* migration logic tested up

* migration up and down tests

* Update validator/db/kv/attester_protection.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* added in pruning and batched migrations

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-02-17 19:23:59 +00:00
Nishant Das
6391dec5de Reform Inbound Limit (#8465)
* clean up

* name

* comment

* change back

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-17 17:48:44 +00:00
Raul Jordan
1ba414bd77 Ignore Analyzers Package in DeepSource Config (#8467) 2021-02-17 16:53:45 +00:00
Radosław Kapka
6f2438436c Implement GetStateFork in the beacon API (#8456)
* update ethereumapis dependency

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

* implement StateByStateRoot

* initial implementation

* tests

* refactor code into smaller functions

* gzl

* simplify StateByStateRoot and tests

* Nishant's feedback

* gzl

* handle error in test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-02-17 09:26:39 -06:00
Nishant Das
2515dc4c06 Clean Up Go Sum (#8462) 2021-02-17 09:30:56 +00:00
terence tsao
2c36e6534c Better feature flag logging (#8457)
* Remove unused core functions

* First take

* Apply for validator

* Use constant

* Use constant
2021-02-16 19:57:42 +00:00
Nishant Das
fe27ca359c Deprecate Uneeded Flags (#8455)
* remove disable pruning flag

* deprecate disable majority vote flag

* remove eth1dataVoteCache

* remove outdated methods

* gaz
2021-02-16 15:27:37 +00:00
Nishant Das
bf7425bae4 rmeove methods (#8454) 2021-02-16 17:56:02 +08:00
Preston Van Loon
558b16275d Validator: Annotate attestation error spans (#8451)
* Annotate attestation spans

* Annotate attestation spans

* gaz

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-16 09:06:52 +00:00
Victor Farazdagi
a069738c20 ETH2 Types: Slot (#8408)
* update shared/params

* update eth2-types deps

* update protobufs

* update shared/*

* fix testutil/state

* update beacon-chain/state

* update beacon-chain/db

* update tests

* fix test

* update beacon-chain/core

* update beacon-chain/blockchain

* update beacon-chain/cache

* beacon-chain/forkchoice

* update beacon-chain/operations

* update beacon-chain/p2p

* update beacon-chain/rpc

* update sync/initial-sync

* update deps

* update deps

* go fmt

* update beacon-chain/sync

* update endtoend/

* bazel build //beacon-chain - works w/o issues

* update slasher code

* udpate tools/

* update validator/

* update fastssz

* fix build

* fix test building

* update tests

* update ethereumapis deps

* fix tests

* update state/stategen

* fix build

* fix test

* add FarFutureSlot

* go imports

* Radek's suggestions

* Ivan's suggestions

* type conversions

* Nishant's suggestions

* add more tests to rpc_send_request

* fix test

* clean up

* fix conflicts

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: nisdas <nishdas93@gmail.com>
2021-02-16 07:45:34 +00:00
Preston Van Loon
aef5a7b428 Validator: Choose a reasonable cap for the attested target epochs slice (#8452)
* Choose a reasonable cap for the attested target epochs slice

* revert bazelrc

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-16 01:37:35 +00:00
terence tsao
4bed8d4ed4 Remove unused core functions (#8449)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-15 22:50:50 +00:00
ahadda5
f4a6b90e8b Mask credentials for logging (#8429)
* Added MaskCredentialsLogging to logutil, which masks the user info, path and query. It leaves the hostname and port untouched . Making it more secure during logging

* Added MaskCredentialsLogging to logutil, which masks the user info,path and query. It leaves the hostname and port untouched . Making it more secure during logging

* Added newline based on the PR checks

* Update shared/logutil/logutil.go

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

* Update shared/logutil/logutil.go

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

* Gazelle

* Update shared/logutil/logutil.go

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

* Update shared/logutil/logutil.go

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

* added unit tests

* updated one test case

* added logutil_test.go unit test cases

* Refactor validator subnet subscriptions to be non-blocking (#8319)

* Use response.NextEpochDuties for aggregator subnet subscriptions (credit: @KaanKC PR #8204). Make committee subnet subscriptions method non-blocking call

* Fix test

* Fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>

* Add Ability to Specify All Public Keys When Exiting Validators (#8399)

* add programmatic voluntary exit

* add exit all flag

* test

* lint

* add multiple exits test

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* Increase Validation Queue (#8431)

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* Validator: add a DEBUG log to show batch attestation save duration (#8432)

* Add a debug log to show duration

* Autofix issues in 1 file

Resolved issues in validator/db/kv/attester_protection.go via DeepSource Autofix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>

* Add Mutex and Block Profiling (#8435)

* Implement GetStateRoot in the beacon API (#8402)

* update ethereumapis dependency

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* On Block Cleanup (#8438)

* Beacon API: update GetStateRoot  (#8437)

* Address various feedbacks

* Gaz

* More nil check

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

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

* qualifying my unix user ahaddad - no real changes to the files

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-02-15 21:54:19 +00:00
Raul Jordan
36b6a71af4 Configurable DB Mmap Size for Beacon Node and Validator Client (#8448)
* add flag to beacon and validator

* gaz

* fuzz

* add dep viz

* add to tools
2021-02-15 20:29:47 +00:00
Raul Jordan
7c3827a9a4 add test (#8444) 2021-02-15 11:55:28 -06:00
Potuz
d17f210024 Log Block Processing Time (#8441)
* Log Block Processing Time instead of time in slot

* Restore timeSinceSlotStart

* Renamed fields

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-02-15 10:33:38 -06:00
terence tsao
28631e7791 Verify nil block helper (#8447) 2021-02-15 15:11:25 +00:00
terence tsao
28839fbab2 Use latest block header + slot as skip slot cache key (#8443) 2021-02-13 23:13:20 +00:00
Radosław Kapka
0716519be9 Fix error formatting inside fmt.Errorf (#8439)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-12 23:44:46 +00:00
terence tsao
068f758f49 Code inspect - clean ups (#8445) 2021-02-12 17:04:45 -06:00
Preston Van Loon
e2c5ae53e7 Validator: Safer pending attestation records flushing (#8433)
* Add a debug log to show duration

* merge from dev

* use safe pending attestation records struct

* fix build, use atomic bool

* Add deadline checks to CheckSlashableAttestation

* Go fmt

* Add test for in-progress log

* GoDocs

* Rename pending attestation records to queued attestation records

* rename and add commentary on log

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-12 20:19:01 +00:00
Preston Van Loon
473172ca8b Validator: Make read operation use db.view instead of db.update (#8434)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-12 19:06:58 +00:00
Radosław Kapka
47fdb3b99a Revert "Rename NewService to New (#8337)" (#8440)
* Revert "Rename `NewService` to `New` (#8337)"

This reverts commit d121b19145.

# Conflicts:
#	beacon-chain/sync/initial-sync/round_robin_test.go

* fix name in test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-12 17:45:22 +00:00
terence tsao
143d3a3203 Process attestation: skip if forkchoice attestation count == 0 (#8436)
* Cont. if there's no fork choice attestations

* Comment

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-02-12 17:11:42 +00:00
terence tsao
66471c2f13 Beacon API: update GetStateRoot (#8437)
* Address various feedbacks

* Gaz

* More nil check

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

* Update beacon-chain/rpc/beaconv1/state_test.go

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

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-02-12 15:38:36 +00:00
Nishant Das
7f6b15271a On Block Cleanup (#8438) 2021-02-12 11:36:53 +00:00
Radosław Kapka
cbb0f1e11d Implement GetStateRoot in the beacon API (#8402)
* update ethereumapis dependency

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-11 21:08:36 +00:00
Raul Jordan
25caa6d1be Add Mutex and Block Profiling (#8435) 2021-02-11 20:20:19 +00:00
Preston Van Loon
d551c8e1d0 Validator: add a DEBUG log to show batch attestation save duration (#8432)
* Add a debug log to show duration

* Autofix issues in 1 file

Resolved issues in validator/db/kv/attester_protection.go via DeepSource Autofix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2021-02-11 18:27:35 +00:00
Nishant Das
2fd2bafdfa Increase Validation Queue (#8431)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-11 17:35:52 +00:00
Raul Jordan
e236dedc32 Add Ability to Specify All Public Keys When Exiting Validators (#8399)
* add programmatic voluntary exit

* add exit all flag

* test

* lint

* add multiple exits test

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-11 16:50:16 +00:00
Preston Van Loon
7d2f7ae9e1 Refactor validator subnet subscriptions to be non-blocking (#8319)
* Use response.NextEpochDuties for aggregator subnet subscriptions (credit: @KaanKC PR #8204). Make committee subnet subscriptions method non-blocking call

* Fix test

* Fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-02-11 16:09:17 +00:00
Nishant Das
ed9c69ec61 Use a Slim Base Image for our Cross-Build Toolchain Docker Image (#8425)
* change it to slim

* update

* Ran regenerate.sh

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-02-11 03:03:15 +00:00
Ivan Martinez
b6a40094a6 Exclude unexported fields for protos in sszutils.DeepEqual (#8415)
* Fix deep equal

* Fixes

* gaz

* Fix test

* Add UnexportedOnly function

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 23:00:18 +00:00
terence tsao
de15d6d2c1 Some improvements to proposer cache (#8424)
* Revert to use input epoch

* Revert back to process epoch

* Use processed state

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 22:07:12 +00:00
Nishant Das
143cb142bc Make Individual Validators Immutable (#8397)
* initial POC

* clean up

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 20:52:45 +00:00
terence tsao
d3e93dd106 Process attestation: reduce checkpoint copies (#8409)
* Clean up process attestation

* Add matching getters

* Fix tests

* Update tests

* Fix test

* Remove read locks

* Typo

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 19:30:11 +00:00
terence tsao
56c5938898 Send feed faster with UpdateHeadTimely feature flag (#8422)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 18:26:23 +00:00
terence tsao
d44ab1ace5 Add timeSinceSlotStart field to "Synced new block..." log (#8420)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-10 17:24:40 +00:00
Nishant Das
ae028d9c1d Insert Finalized Deposits In Another Routine (#8405)
* chk

* terence's review

* add test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-10 10:35:44 -06:00
Preston Van Loon
cbd01d4ff4 Provide TLS certificate to gRPC gateway (#8418)
* Provide TLS certificate to gRPC gateway

* Provide TLS certificate to gRPC gateway

* Provide TLS certificate to gRPC gateway

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 04:23:12 +00:00
Victor Farazdagi
65645face1 Update ethereumapis deps (#8417)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-10 03:33:33 +00:00
Ivan Martinez
cd3851c3d5 Add DeepSSZEqual and DeepNotSSZEqual (#8421) 2021-02-09 20:57:22 +00:00
terence tsao
2f98e6aaaf Update head per slot (#8381)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-09 17:24:48 +00:00
terence tsao
9afc9d92d9 Feature flag: update head timely (#8412)
* Feature flag: update head timely

* Move finalized imply justified up

* Fix resolve error

* Use invert feature flag

* Make diff easier to review

* Line

* Typo

* Fix condition

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-09 15:35:14 +00:00
Victor Farazdagi
a8e501b3cf ETH2 Types: Epoch (#8373)
* update deps

* update deps

* update protos/*

* update deps

* reset protos

* update protos

* update shared/params/config

* update protos

* update /shared

* update shared/slotutil and shared/testutil

* update beacon-chain/core/helpers

* updates beacon-chain/state

* update beacon-chain/forkchoice

* update beacon-chain/blockchain

* update beacon-chain/cache

* update beacon-chain/core

* update beacon-chain/db

* update beacon-chain/node

* update beacon-chain/p2p

* update beacon-chain/rpc

* update beacon-chain/sync

* go mod tidy

* make sure that beacon-chain build suceeds

* go fmt

* update e2e tests

* update slasher

* remove redundant alias

* update validator

* gazelle

* fix build errors in unit tests

* go fmt

* update deps

* update fuzz/BUILD.bazel

* fix unit tests

* more unit test fixes

* fix blockchain UTs

* more unit test fixes
2021-02-09 10:05:22 +00:00
Preston Van Loon
5727d4eb8a Update Herumi with a fix for older intel chips (#8413)
* Update Herumi with a fix for older intel chips. #8410

* Use the correct version of bls-eth-go-binary
2021-02-09 01:44:27 +00:00
terence tsao
fed65122fe Use EnableNextSlotStateCache few more places (#8398) 2021-02-08 13:11:21 -08:00
Radosław Kapka
86a9d4c6a4 Configurable testutil's BeaconState (#8407)
* Configurable testutil's BeaconState

* fix shared and fuzz tests

* return state copy

* use mainnet config values for default state

* handle error in block fuzz

* goimports

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-08 20:00:09 +00:00
Panagiotis Georgiadis
0a180dc662 Make a const instead of 3 'abc' occurences (#8406) 2021-02-08 17:08:29 +01:00
terence tsao
f9303ca2e4 Clean up unused functions (#8403)
* Clean ups

* Gazelle
2021-02-05 18:39:15 +00:00
terence tsao
4c25fe978a Update span names (#8394)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-04 20:23:50 +00:00
terence tsao
cf88afb287 Block validator buckets (#8395)
* Block validator buckets

* add more buckets to blocked collector list

Co-authored-by: rauljordan <raul@prysmaticlabs.com>
2021-02-04 03:30:09 +00:00
Victor Farazdagi
c97ea766ca Attestation aggregation: optimizations and benchmarks (#7938)
* profitablity tests

* cleanup benchmark

* fix deduplication function

* dedup: move method to atts list

* proper substring handling

* refactor validate method

* update benchmarks

* prepare proposer test

* remove redundant code

* reset test

* remove dedup from maxcover - moved to proposer

* remove redundant test

* remove lower level check for bit length

* optimize candidate validation on att aggregation

* restore test

* fix test

* fix test

* remove dedup functionality

* add benchmark

* optimize list usage

* Attestation aggregration: remove redundant dedup routine

* fix func call

* experiment with bitset based cover

* add benchmark

* samplem implementation using Bilist64

* add tests

* remove redundant code

* remove tmp comments

* unskip test

* update benchmarks

* gazelle

* process err

* optimized max-cover

* Max-cover: optimized implementation based on Bitlist64

* gazelle

* re-arrange overlaps check

* minor comments

* add Bitlists64WithMultipleBitSet

* update benchmarks

* gazelle

* add TestAggregateAttestations_rearrangeProcessedAttestations

* minor updates to rearrange method

* add link to design doc

* remove redundant methods

* simplify test

* add TestAggregateAttestations_aggregateAttestations

* fix issues

* fix assignment

* use ToBitlist(), ToBitlist64()

* fixes test

* benchmarks

* fix typo

* allow opt_max_cover opt-int flag

* update benchmarks

* reset e2e

* fix test

* enable opt_max_cover in e2e tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-04 00:58:33 +00:00
Preston Van Loon
e52a821f73 Validator testing library should be marked as testonly (#8392)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-03 23:16:41 +00:00
Nishant Das
d4f241d875 Add Custom Deadline for Slot Progression (#8388)
* use custom deadline

* revert

* preston's comment

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-03 21:39:54 +00:00
Preston Van Loon
48ae49765e Revert "Change sszutil DeepEqual to ignore unexported fields" (#8391)
* Revert "Change sszutil DeepEqual to ignore unexported (#8336)"

This reverts commit 8d986bd414.

* Add back tests, make tests have equal and non equal check

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-03 20:39:07 +00:00
Raul Jordan
afa5b5e790 Add Spans for Validator DB Methods (#8390)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-03 19:29:20 +00:00
Preston Van Loon
c5551ebebb Revert DEPENDENCIES.md change from #8257 (#8389) 2021-02-03 18:46:46 +00:00
terence tsao
616081fbdd Ran code inspect (#8387) 2021-02-03 10:59:17 -06:00
Victor Farazdagi
842bafb002 Update bitfield dependency (#8385) 2021-02-02 21:33:48 +00:00
Raul Jordan
953cc9733c Update Ethdo Keystore Deps (#8382)
* update ethdo deps

* revert workspace

* tidy
2021-02-02 19:05:47 +00:00
Raul Jordan
caac08df33 Add Batch Method for Reading Validator Proposing Histories (#8378)
* add in batch method

* add in new proposal history methods for efficiency and progress bars

* tests fixed to use the new methods

* add back get slot proposing history method

* add gaz
2021-02-02 15:53:12 +00:00
Radosław Kapka
3fd8c4c046 Implement GetGenesis in the beacon API (#8380)
* span

* initial implementation

* test wip

* set nanos to zero

* more testing

* gzl
2021-02-02 08:44:28 -06:00
Radosław Kapka
b5a82b9075 Display URLs for tracking exited validators (#8361)
* Display URLs for tracking exited validators

* extract displaying info to separate function

* fix URL comment

* extract config names

* gzl

* lowercase config names

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-01 19:00:06 +00:00
Nishant Das
c6e96204e8 Update Herumi BLS Library (#8377)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-01 18:31:48 +00:00
terence tsao
2456e6f34d Add missed feature flag usage (#8376)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-01 17:42:50 +00:00
Radosław Kapka
48ed506487 Ajust constructor names of nodes (#8362)
* clean up constructors for nodes

* resurrect validator client

* fix small naming issues

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-01 17:12:52 +00:00
Shay Zluf
4595789ac8 Make validator stable when beacon node goes offline (#8278)
* Make validator stable POC

* fix feedback raul and nishant

* fix wait till first iteration

* fix imports

* retry tests

* fix init

* test retry receive blocks

* remove redundant return statement

* terence feedback

* terence feedback

* remove log

* to check for context after fist call

* remove fatal

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-02-01 16:29:54 +00:00
Victor Farazdagi
d53fdcf781 Simplify expressions (#8370)
* Simplify expressions

* avoid escaping

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-01 15:14:36 +00:00
Victor Farazdagi
372dc47b64 Deprecate enableSyncBacktracking flag (#8371)
* Deprecate enableSyncBacktracking flag

* keep deprecated flags
2021-02-01 11:18:24 +00:00
pinglamb
82426abf5f Add canonical flag to ListBlocks API response (#8287)
* Add canonical flag to ListBlocks response

* Genesis is always canonical
2021-02-01 04:33:17 +00:00
terence tsao
f5f1284cef Remove unused feature flag config fields (#8363)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-30 15:16:31 +00:00
terence tsao
609418ecd3 Update README.md (#8366)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-30 14:28:27 +00:00
Radosław Kapka
f20c9122e8 Remove unused channel from Powchain Service (#8368)
* Remove unused header channel

* test fix

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-01-30 13:33:52 +00:00
Ivan Martinez
afc3b3168a Add Back Accounts Backup Validator RPC Functionality (#8367)
* Add Back Accounts Backup Validator RPC Functionality

This reverts commit a39db494eb.

* Fix
2021-01-29 18:30:44 -06:00
Victor Farazdagi
902c30e389 Update bitfield dependency (#8364) 2021-01-29 19:58:26 +00:00
terence tsao
3aaa98decf Next slot state caching (#8357)
* Add and use trailing slot state cache

* Remove comment

* Update comments

* Update comments

* Move it to background

* Warn is more appropiate

* Raul's comment

* Same strategy for proposer

* Own helper

* Minor touchups

* Tests

* Feature flag

* Gaz
2021-01-29 16:52:43 +00:00
Ivan Martinez
e592cd7a80 Add wallet file flag to edit-config command (#8360) 2021-01-29 09:32:15 +00:00
Nishant Das
b74dd967af Bind Discovery Using Neutral Network Version (#8359)
* fix it

* terence's review
2021-01-29 15:07:32 +08:00
Victor Farazdagi
d254f24a23 Update bitfield dependency (#8356) 2021-01-29 00:39:29 +00:00
Radosław Kapka
8d505e06bd Implement GetForkSchedule in the config API (#8345)
* span

* update ethereumapis

* implementation + tests

* typo

* fix variable shadowing

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-28 13:44:23 -06:00
Victor Farazdagi
09b1e06885 Max-cover: optimized implementation based on Bitlist64 (#8352)
* Max-cover: optimized implementation based on Bitlist64

* gazelle

* re-arrange overlaps check

* minor comments

* add Bitlists64WithMultipleBitSet

* update benchmarks

* gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-28 15:55:02 +00:00
Radosław Kapka
d9c451d547 Introduce helper function for adding context metadata from gRPC headers (#8354)
* implement helper

* use helper function everywhere

* add unit tests

* small cleanup of the helper

* small fixes

* gazellelelele

* fix helper tests
2021-01-28 08:58:32 -06:00
Radosław Kapka
e677b19d31 Implement GetSpec in the config API (#8328)
* Implement GetSpec in the config API

* extract map creation

* fix deepsource compliant

* Revert "fix deepsource compliant"

This reverts commit 0c99310cc9.

* use struct tags for api map keys

* remove log

* use spec tag

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-28 00:30:48 +00:00
terence tsao
2bf03d5cba Use strings builder for attester lock key (#8349)
* Use strings builder

* Handle error
2021-01-27 22:33:28 +00:00
terence tsao
0753636159 Add role based lock for validator (#8347) 2021-01-27 20:59:21 +00:00
terence tsao
b8037b0b50 Wait for one third before grabbing the lock (#8348) 2021-01-27 12:06:18 -06:00
Tushar Shah
2f063d0ddc process grpc header flag for exit (#8334)
* process grpc header flag for exit

* ran bazel //:gazelle

* Add regression test

* Re-run "bazel run //:gazelle"

* whitespace

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* gofmt

Co-authored-by: Danny Joyce <djoyce@bisontrails.co>
Co-authored-by: Danny Joyce <djoyahoy@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-27 13:12:48 +00:00
terence tsao
1cfae7e098 More blockchain pkg tests (#8343)
* Add more blockchain pkg tests

* Deepsource feedback

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-26 20:27:34 -06:00
terence tsao
91fe32a3d1 Handle subscriber error (#8341) 2021-01-26 13:56:24 -06:00
terence tsao
c0fda583e7 Update seen att slashing cache to use map (#8332)
* Hide beacon operation field if it's 0

* Use map as seen slashing cache

* Revert "Hide beacon operation field if it's 0"

This reverts commit 896fa11a0b.

* Rm unused code

* Gaz

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-26 17:24:34 +00:00
Nishant Das
9f62405a81 Update Prombolt Collector (#8339)
* update

* block big buckets

* add more buckets

* patch go.mod

* clean up

* Update beacon-chain/db/kv/kv.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-01-26 15:32:46 +00:00
terence tsao
d121b19145 Rename NewService to New (#8337)
* Hide beacon operation field if it's 0

* Rename NewSerivce to New

* Revert "Hide beacon operation field if it's 0"

This reverts commit 896fa11a0b.

* Fix NewServiceRegistry

* Update slasher/detection/service.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-26 10:26:57 +00:00
Radosław Kapka
a7345c1094 Implement GetDepositContract in the config API (#8316)
* Add funnction to retrieve deposit contract's address from powchain

* change bytes.Equal to assert.DeepEqual

* add DepositContractAddress to mocks

* Extract powchain info to a separate struct

* span

* Revert "Extract powchain info to a separate struct"

This reverts commit e01dd5222b.

* implementation + test

* use the correct hexutil library

* read contract address from configuration

* return ETH1 chain ID instead of fork version

* gzl (I hate you)

* remove unused ChainInfoFetcher

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-01-26 09:37:22 +00:00
Victor Farazdagi
db79481c21 Update bitfield dependency (#8338) 2021-01-26 08:35:16 +00:00
Ivan Martinez
8d986bd414 Change sszutil DeepEqual to ignore unexported (#8336) 2021-01-25 17:52:41 -06:00
Radosław Kapka
c827672a30 Rename non-generated files ending with '_mock' (#8317)
* rename *_mock files

* bzl

* rename faulty_mock_powchain

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-25 22:30:55 +00:00
terence tsao
d5ec248691 Rename getter functions to be idiomatic (#8320)
* Rename getter functions

* Rename new

* Radek's feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-25 21:27:30 +00:00
Nishant Das
b2d6012371 Fix IPV6 binding for Beacon Node (#8326)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-25 20:10:41 +00:00
Radosław Kapka
d21365b882 Remove test assertion that reads a package-level variable (#8329)
* remove checking value of shared variable

* fix deepsource compliant

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-25 18:27:59 +00:00
Nishant Das
1c43ea9e69 Update the Toolchain Registration (#8322)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-25 16:46:27 +00:00
Radosław Kapka
fc8dc21aa2 Cancel node context after StopAll (#8289)
* cancel node context after StopAll

* build fix

* cancel in validator

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-01-25 09:57:21 -06:00
Nishant Das
7f5ffb7dd1 Fix Deadlock in Runtime (#8321)
* fix deadlock

* fix

* Satisfy Deepsource

* fmt
2021-01-25 11:01:55 +08:00
Raul Jordan
92932ae58e [Feature] - Slashing Interchange Support (#8024)
* Change LowestSignedProposal to Also Return a Boolean for Slashing Protection (#8020)

* amend to use bools

* ineff assign

* comment

* Update `LowestSignedTargetEpoch` to include exists (#8004)

* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

* Add eip checks to ensure epochs cant be lower than db ones

* Should be less than equal to

* Check if epoch exists in DB getters

* Revert run time checks

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* Export Attesting History for Slashing Interchange Standard (#8027)

* added in att history checks

* logic for export

* export return nil

* test for export atts

* round trip passes first try!

* rem println

* fix up tests

* pass test

* Validate Proposers Are Not Slashable With Regard to Data Within Slasher Interchange JSON (#8031)

* filter slashable blocks and atts in same json stub

* add filter blocks func

* add test for filtering out the bad public keys

* Export Slashing Protection History Via CLI (#8040)

* include cli entrypoint for history exports

* builds properly

* test to confirm we export the data as expected

* abstract helpers properly

* full test suite

* gaz

* better errors

* marshal ident

* Add the additional eip-3076 attestation checks (#7966)

* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

* Add eip checks to ensure epochs cant be lower than db ones

* Should be less than equal to

* Check if epoch exists in DB getters

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Add EIP-3076 Invariants for Proposer Slashing Protection (#8067)

* add invariant for proposer protection

* write different test cases

* pass tests

* Add EIP-3076 Interchange JSON CLI command to validator (#7880)

* Import JSON CLI

* CLI impotr

* f

* Begin adding new commands in slashing protection

* Move testing helpers to separate packae

* Add command for importing slashing protection JSONs

* fix import cycle

* fix test

* Undo cleaning changes

* Improvements

* Add better prompts

* Fix prompt

* Fix

* Fix

* Fix

* Fix conflict

* Fix

* Fixes

* Fixes

* Fix exported func

* test func

* Fixes

* fix test

* simplify import and standardize with export

* add round trip test

* true integration test works

* fix up comments

* logrus

* better error

* fix build

* build fix

* Update validator/slashing-protection/cli_export.go

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

* Update validator/slashing-protection/cli_import.go

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

* fmt

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

* Filter Slashable Attester Public Keys in Slashing Interchange Import (#8051)

* filter slashable attesters from the same JSON

* builds

* fix up initially broken test

* circular dep

* import fix

* giz

* added in attesting history package

* add test for filter slashable attester keys

* pass tests

* Save Slashable Keys to Disk in the Validator Client (#8082)

* begin db funcs

* add in test and bucket

* gaz

* rem changes to import

* ineff assign

* add godoc

* Properly Handle Duplicate Public Key Entries in Slashing Interchange Imports (#8089)

* Prevent Blacklisted Public Keys from Slashing Protection Imports from Having Duties at Runtime (#8084)

* tests on update duties

* ensure the slashable public keys are filtered out from update duties via test

* begin test

* attempt test

* rename for better context

* pass tests

* deep source

* ensure tests pass

* Check for Signing Root Mismatch When Submitting Proposals and Importing Proposals in Slashing Interchange (#8085)

* flexible signing root

* add test

* add tests

* fix test

* Preston's comments

* res tests

* ensure we consider the case for minimum proposals

* pass test

* tests passing

* rem unused code

* Set Empty Epochs in Between Attestations as FAR_FUTURE_EPOCH in Attesting History (#8113)

* set target data

* all tests passing

* ineff assign

* signing root

* Add Slashing Interchange, EIP-3076, Spec Tests to Prysm (#7858)

* Add interchange test framework

* add checks for attestations

* Import genesis root if necessary

* flexible signing root

* add test

* Sync

* fix up test build

* only 3 failing tests now

* two failing

* attempting to debug problems in conformity tests

* include latest changes

* protect test in validator/client passing

* pass tests

* imports

* spec tests passing with bazel

* gh archive link to spectests using tar.gz suffix

* rev

* rev more comment changes

* fix sha

* godoc

* add back save

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Implement Migration for Unattested Epochs in Attesting History Database (#8121)

* migrate attesting history backbone done

* begin migration logic

* implement migration logic

* migration test

* add test

* migration logic

* bazel

* migration to its own file

* Handle empty blocks and attestations in interchange json and sort interchange json by public key (#8132)

* Handle empty blocks and attestations in interchange json

* add test

* sort json

* easier empty arrays

* pass test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* builds

* more tests finally build

* Align Slashing Interchange With Optimized Slashing Protection (#8268)

* attestation history should account for multiple targets per source

* attempt at some fixes

* attempt some test fixes

* experimenting with sorting

* only one more failing test

* tests now pass

* slash protect tests passing

* only few tests now failing

* only spec tests failing now

* spec tests passing

* all tests passing

* helper function for verifying double votes

* use helper

* gaz

* deep source

* tests fixed

* expect specific number of times for domain data calls

* final comments

* Batch Save Imported EIP-3076 Attestations (#8304)

* optimize save

* test added

* add test for sad path

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>

* revert bad find replace

* add comment to db func

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Shay Zluf <thezluf@gmail.com>
2021-01-22 17:12:22 -06:00
Radosław Kapka
8ffb95bd9d Allow dynamic key reloading when having inactive keys (imported & derived) (#8119)
* restart waiting for activation on key change

* test fixes

* wiat for activation comments

* regression test

* log fatal when validator cast fails

* derived keymanager

* review comments

* add buffer to channel

* simplify key refetch logic

* reload keys into empty wallet

* removed warning on wallet creation

* add empty line

* export AccountsKeystoreRepresentation type

* unit test for handleAccountsChanged

* test ctx cancellation

* add missing mockRemoteKeymanager interface function

* gazelle

* gzl

* fix panic inside goroutine during runner tests

* rename error message variables

* Update validator/accounts/accounts_list_test.go

* reorder imports

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-22 20:21:34 +00:00
terence tsao
229abed848 Test for processAttestations (#8312)
* Add a test for processAttestations

* Log should not contrain could not process attestation...

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-22 18:08:16 +00:00
terence tsao
c5e9b1ec9e Refactor verifyAttestationIndices method (#8309)
* Refactor verifyAttestationIndices

* Conflict

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-22 17:15:49 +00:00
Radosław Kapka
7842fd9da6 Replace bytes.Equal with assert.DeepEqual in tests (#8318)
* beacon chain

* format imports

* Update beacon-chain/db/kv/migration_archived_index_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/db/kv/migration_block_slot_index_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* remove unused imports

* Update beacon-chain/core/state/skip_slot_cache_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/core/state/skip_slot_cache_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/core/state/skip_slot_cache_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/core/state/skip_slot_cache_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/db/kv/migration_archived_index_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

* Update beacon-chain/db/kv/migration_block_slot_index_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-01-22 15:15:40 +00:00
Victor Farazdagi
75fc3b045b Max-cover: minor optimizations (#8311)
* Max-cover: minor optimizations

* fix test
2021-01-22 20:10:50 +08:00
Nishant Das
50e5b1b4f5 fix deposit index metrics (#8315) 2021-01-22 19:11:02 +08:00
Preston Van Loon
33e266388f GetDuties: Refactor assignment status to deduplicate status computation (#8313) 2021-01-21 14:22:05 -08:00
terence tsao
2586be29ac Refactor on_attestation return signature (#8310)
* Update func on_attestation's return signature

* Add return
2021-01-21 18:38:51 +00:00
Radosław Kapka
9cc1438ea9 Peer count node api (#8306)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-21 16:16:56 +00:00
Victor Farazdagi
6e643aca12 Attestation aggregation: baseline benchmark (#8308)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-21 14:29:17 +00:00
Nishant Das
cc5a847eeb update to v1.15.7 (#8307) 2021-01-21 21:27:57 +08:00
Raul Jordan
241322a7c1 Safe Math for ETH1 Batch Headers Request (#8253)
* batch request underflow checks

* Update beacon-chain/powchain/service.go

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

* return error

* Update beacon-chain/powchain/service.go

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

* test

* Apply suggestions from code review

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

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-21 09:19:44 +00:00
Victor Farazdagi
d697b0b2e5 Update bitfield dependency (#8305) 2021-01-21 08:28:57 +00:00
Preston Van Loon
9ec4f727c6 Remove unnecessary state copy (#8303) 2021-01-20 20:00:01 -06:00
terence tsao
ffcadcf184 Rm forkchoice attestation verification (#8301)
* Rm fork choice attestation sig verification

* Unit test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-20 21:46:13 +00:00
Ivan Martinez
7c59615ae2 Remove go-ssz entirely from prysm (#8257)
* Add DepositSigningData

* gaz

* Add to ssz tests

* Rename to DepositMessage

* Remove deprecated comment

* Remove return

* Fixes from review

* Fixes

* Remove some of gossz

* Remove go-ssz entirely

* Remove unneeded file

* Fix runtime with ssztypes

* Add back ssz files

* Fix formatting

* tidy

* Remove go-ssz from static

* tidy again

* Add tests

* Change to sig

* Fix test

* fx

* Fix visiblity

* Revert "Remove unneeded file"

This reverts commit d66fcda929.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-20 21:03:46 +00:00
Preston Van Loon
d6cccc18c3 verifyDepositDataWithDomain: Use helpers.ComputeSigningRoot (#8302) 2021-01-20 20:30:58 +00:00
terence tsao
befe8d88b8 Remove duplicated target root check for fork choice attestation (#8277)
* Rm redundant target root check for fork choice attestation

* Comments

* Revert back verifyBeaconBlock

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-20 18:27:10 +00:00
Radosław Kapka
153737803a Implement ListPeers in the node API (#8288)
* add span

* update ethereumapis

* align server with ethereumapis

* benchmark

* naive implementation

* rename two status functions

* new Inbound and Outbound status functions

* tests

* 'enr:' prefix

* refactoring

* gzl

* case when one filter is empty

* empty filter condition fix

* deepsource

* rename getPeer to peerInfo

* bring back correct version of ethereumapis

* go mod tidy
2021-01-20 15:52:33 +00:00
Radosław Kapka
4b14fa4317 Better receiver names in validator and slasher modules (#8296)
* validator

* slasher

* rename db to s for store

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-20 14:39:07 +00:00
Victor Farazdagi
27847ee2fe Update bitfield dependency (#8299) 2021-01-20 13:39:54 +00:00
terence tsao
578dabe27c Remove duplicated LMD FFG check for fork choice attestation (#8276)
* Rm redundant lmd<->ffg check for fork choice attestation

* Comments

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-20 10:19:43 +00:00
Victor Farazdagi
ed2c0a3e5e Update bitfield dependency (#8295) 2021-01-20 06:55:53 +00:00
terence tsao
5d841874f7 Return error on AttestingIndices bitfield length check (#8285)
* Return error on committee len check

* AttestingIndices unit test

* Add equality check

* Fixing more tests

* Fix rest of the tests

* Fix invalid bit length test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-20 03:00:52 +00:00
terence tsao
ab9d596a5f Update fastssz (#8291)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-19 23:48:22 +00:00
terence tsao
084e5bd020 Add test TestStore_OnAttestation_Ok (#8293)
* Add test TestStore_OnAttestation_Ok

* Handle errors

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-19 23:10:10 +00:00
terence tsao
bc2c206832 Add verify slot target epoch function and apply all (#8273)
* Add verify slot target epoch function and apply all

* Fix TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-19 21:41:44 +00:00
Preston Van Loon
655a7e98c3 Stamp binaries by default (#8292) 2021-01-19 20:43:30 +00:00
Radosław Kapka
f89fd67952 Better receiver names in beacon chain module (#8286) 2021-01-19 13:21:32 +00:00
Nishant Das
20b836d038 Add Initial Support For Gossip Scoring Service (#8275)
* checkpoint progress

* gaz

* fix

* add it in

* Update beacon-chain/p2p/pubsub.go

* fmt

* reformat imports

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-01-19 12:13:08 +00:00
Preston Van Loon
b33a8eb59f Revert "Use remote cache in CI" (#8281)
This reverts commit 8b6abcbf0c.
2021-01-19 01:55:00 +00:00
Preston Van Loon
8b6abcbf0c Use remote cache in CI (#8280)
* Use remote cache in CI

* Update .buildkite-bazelrc

* Update .buildkite-bazelrc
2021-01-18 22:22:37 +00:00
Raul Jordan
9b367b36fc add happy/sad tests (#8279) 2021-01-18 11:32:17 -08:00
pinglamb
09a792ded4 isCanonical for slot 0 should return true (#8269)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-16 16:14:14 +00:00
terence tsao
cf343be76a Add a helper to validate nil attestation (#8272)
* Add verify nil attestation function and apply all

* Remove invalid attestatione debug log

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-15 22:19:17 +00:00
Raul Jordan
4c19e622cd Implement Migration Up/Down Logic for Validator DB (#8271)
* rollback logic

* implement up down logic

* begin down migration tests

* rollback works

* unset test

* remove iface

* gaz

* add comment

* fix ineff assign

* preston comment

* add progress
2021-01-15 15:35:21 -06:00
pinglamb
d7d2c6354b Blocks filtering should return genesis when startSlot=0 and endSlot=0 (#8270)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-15 18:36:17 +00:00
terence tsao
b6c4bc197f Add on_block finality test (#8266)
* Can generate at epoch boundary

* Remove extra space

* Add on block finality test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-15 13:42:49 +00:00
Nishant Das
ce397ce797 Prune Excess Peers Better (#8260)
* add method

* add changes

* formatting

* choose

* fix waitgroup

* add

* add debug logs

* gaz

* make it better

* fix

* godoc

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-14 21:28:20 +00:00
Radosław Kapka
2d75b12791 Implement GetIdentity in the node API (#8230)
* initial implementation

* register metadata provider

* final implementation

* tests

* fixed imports

* gazelle

* code review

* small cleanup

* change errors.Wrap to status.Errorf

* gazelle + goimports

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-14 20:48:40 +00:00
terence tsao
40155c9828 Testutil: Can generate attestation at epoch boundary (#8265) 2021-01-14 10:22:53 -08:00
Radosław Kapka
a2d4e3302c Implement GetPeer in the node API (#8264)
* tests

* capitalize error message
2021-01-14 10:26:16 -06:00
Nishant Das
612e6ebdc4 gogo protobuf (#8263) 2021-01-14 17:17:26 +08:00
Raul Jordan
fff6472a04 Allow Multiple Targets Per Source Epoch in Attester Protection (#8262) 2021-01-13 23:23:29 +00:00
terence tsao
daf6da5beb Add hydrate indexed att test helper (#8261)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-13 22:05:57 +00:00
pinglamb
9369bb6781 Copied over ssz.DeepEqual as sszutil.DeepEqual from go-ssz (#8258)
* Copied over ssz.DeepEqual as sszutil.DeepEqual from go-ssz

* Added test cases for DeepEqual

* Remove commented code
2021-01-13 20:40:56 +00:00
terence tsao
eeda9f18fe Disallow duties request where req.Epoch > current.Epoch+1 (#8252)
* Disallow request epoch to be out of bound

* Input Slot and epoch checks

* Tests

* Review feedbacks

* Unavailable error code

* Rename genesis time fetcher to time fetcher

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 23:27:37 +00:00
Preston Van Loon
e967a65b68 Update prometheus/client_golang (#8256) 2021-01-12 22:56:57 +00:00
Preston Van Loon
c87ef2f0e7 Coverage results upload fix for CI (#8255)
* Check in gocovmerge, add all-in-one coverage.sh script for CI

* annotate script

* Annotate tools/gocovmerge/main.go

* deepsource suggestions
2021-01-12 20:12:09 +00:00
pinglamb
1a9207ba46 Removed some simple go-ssz usage (#8250)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-12 19:31:34 +00:00
pinglamb
9f423617cb Added db.BlocksBySlot and db.BlockRootsBySlot (#8184)
* Added blockBySlot and blockRootBySlot

* Changed to BlocksBySlot and BlockRootsBySlot

* Updated to use BlocksBySlot and BlockRootsBySlot

* Added missing passthrough to karfa exporter

* Return hasBlocks/hasBlockRoots in the new getters

* Fixed CI lint

* Replace call to bytes.Compare with bytes.Equal

* Reordered the returns of the new getters

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-12 18:31:15 +00:00
Radosław Kapka
015102c2d5 Implement GetSyncStatus in the node API (#8241)
* Implement GetSyncStatus in the node API

* gazelle

* add HeadSlot function to fuzz tests' fakeChecker

* use HeadFetcher to get head slot

* remove useless code

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 17:17:20 +00:00
Radosław Kapka
aa69e5edcc Allow to create an empty imported wallet (#8251)
* reload keys into empty wallet

# Conflicts:
#	validator/accounts/accounts.go

* removed warning on wallet creation

* export AccountsKeystoreRepresentation type

* rename error message variable

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 16:52:01 +00:00
Radosław Kapka
5dda2ca328 Replace HTTP code with gRPC code in GetHealth API endpoint (#8249)
* Replace HTTP code with gRPC code in GetHealth API endpoint

* gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 16:20:20 +00:00
Raul Jordan
470d5aa491 Cleanup Attester DB Protection Files and Add Back Save Lowest Epochs Functionality (#8232)
* cleanup for att protection

* rename to deprecated

* rem old item

* imports
2021-01-12 09:32:13 -06:00
Raul Jordan
d2bd954a6c Remove Snappy from Validator Slashing Protection DB (#8248)
* no snappy

* Update validator/db/kv/migration_optimal_attester_protection.go

* fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 01:10:11 +00:00
Ivan Martinez
e5556db49d Add DepositMessage in preparation to remove go-ssz (#8244)
* Add DepositSigningData

* gaz

* Add to ssz tests

* Rename to DepositMessage

* Remove deprecated comment

* Remove return

* Fixes from review

* Fixes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-12 00:45:11 +00:00
Raul Jordan
d97596348e Add Back New Attester Protection DB Logic (#8242)
* Revert "Revert New Attester Protection DB Logic (#8237)"

This reverts commit 6738fa3493.

* Batch Attestation Records and Flush All at Once in Validator DB (#8243)

* begin flushing logic

* finalize logic before starting tests

* make code DRY

* better log fields

* gaz

* tweak parameter

* rename

* clarifying comment on error handling in event feed

* comprehensive tests

* more comments

* explain parameters in comments

* renamed consts

* Apply suggestions from code review

* gaz

* simplify

* typo

* comments
2021-01-11 23:59:17 +00:00
terence tsao
323eac6d6c Remove timeout debug log (#8247)
* Disallow request epoch to be out of bound

* Remove debug log

* Revert "Disallow request epoch to be out of bound"

This reverts commit d2dc7db594.
2021-01-11 22:23:13 +00:00
Radosław Kapka
5fd03f8fb0 Unify the pattern of using a package-level logger (#8245)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-11 20:03:28 +00:00
terence tsao
18bb86754a Hydrate signed block helper (#8246)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-01-11 19:27:30 +00:00
Preston Van Loon
97320a0a8e Remove snappy compression migration for attestation history (#8238)
* Remove snappy compression migration for attestation history

* gofmt

* remove more snappy stuff

* revert validator/db/kv/historical_attestations.go
2021-01-11 09:28:34 -08:00
terence tsao
9a1866b735 Hydrate header test helper (#8234)
* Hydrate headers and fix tests

* Gazelle

* Fix a slashing test

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-01-09 16:45:45 +00:00
Raul Jordan
6738fa3493 Revert New Attester Protection DB Logic (#8237)
* Revert "Optimize Migration for new Attester Protection DB (#8231)"

This reverts commit c4ab67832f.

* Revert "Integrate New Slashing Protection DB Methods at Runtime (#8219)"

This reverts commit 3858068201.

* Revert "DB Migration for Optimal Local Slashing Protection (#8212)"

This reverts commit dd3ac6c2ed.
2021-01-09 04:00:56 +00:00
terence tsao
35ed01e36c Add timely attest flag to fix #8185 (#8235) 2021-01-08 17:54:46 -08:00
Raul Jordan
c4ab67832f Optimize Migration for new Attester Protection DB (#8231)
* migrate using tx commit

* add improvement

* fixed up test

* rem fmt

* gaz

Co-authored-by: nisdas <nishdas93@gmail.com>
2021-01-08 17:31:54 +00:00
Nishant Das
0ff2a53b2f Add Peer Logger (#8226)
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-01-08 11:08:11 +00:00
Preston Van Loon
25bba9f43f Fuzzing: conditional BLS enabled via environment variable (#8229)
* Read whether or not to enable BLS via environment variable

* Read whether or not to enable BLS via environment variable
2021-01-08 05:31:24 +00:00
Raul Jordan
3858068201 Integrate New Slashing Protection DB Methods at Runtime (#8219)
* integrate at runtime and revamp tests

* historical att

* Update validator/db/iface/interface.go

* deepsource

* import

* log the slashing kind

* gaz

* create a slashutils

* integrate new slashutil

* imports
2021-01-07 23:30:25 +00:00
Raul Jordan
0d5e2cfb27 Prune Validator Attester Records Older than Weak Subjectivity Periods (#8221)
* pruning and begin test

* comprehensive pruning tests

* add pruning on startup

* also prune source epochs bucket

* more testing

* greatly simplify pruning function

* pruning logic and comprehensive tests in

* att protection test

* gaz

* fix sneaky change

* rev

* documented and tested helper func
2021-01-07 15:40:37 -06:00
terence tsao
bc650c82b4 Hydrate attestation for tests (#8228) 2021-01-07 21:00:21 +00:00
Nishant Das
a855f282c6 Fix to TLS v1.3 (#8222)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-07 19:56:51 +00:00
Raul Jordan
4253888a36 Update Bitfield Dependency (#8227)
* bitfield updates

* tidy

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-07 18:12:49 +00:00
Nishant Das
fb9f4e828d Update FastSSZ To Latest Commit (#8225)
* update fast-ssz

* fix

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-07 17:08:41 +00:00
terence tsao
9ff825a570 Update variable names that are same as imports (#8220)
* Fix names that are same as import name

* Review feedbacks
2021-01-07 10:42:03 -06:00
Victor Farazdagi
d20065218c Max-cover: remove redundant dedup routine (#8224)
* Attestation aggregration: remove redundant dedup routine

* fix func call

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-07 14:18:29 +00:00
Radosław Kapka
353c1f6387 Multiple discovery addresses (#8203)
* multiple discovery addresses

* ipv6 fix

* make len test more robust

* create enr node for testing

* use local node for test

* use mockListener

* remove unused type alias
2021-01-07 13:35:42 +00:00
pinglamb
1b6a0703e3 Show number of user pubkeys for attesting and proposing in "Next duty" log output (#8187)
* Show attesting and proposing counts in "Next duty" log output

* Use map to store all the counts instead of magic reset

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2021-01-07 10:22:38 +00:00
pinglamb
9135774720 Block Fetching with Graceful Retry (#8182)
* Added tooMuchDataRequestedError func

* Added multiplicative decrease and additive increase

* Code review changes

* Renaming the new constants

* Return a different error in graceful retry

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-01-07 06:21:44 +00:00
Potuz
e52c3d48cf Start from last valid root in loadStateBySlot (#8218)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-01-06 18:41:44 -06:00
terence tsao
ba9b563e6e Fix Attest early if valid block is received before 4 seconds (#8197)
* Better int -> string conversion

* First take

* More tests

* Gazelle

* Remove validator subpackage visiblity

* Remove span

* Update validator/client/attest.go

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

* Update validator/client/attest.go

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

* Update stream blocks call to use verified only

* Rename to waitOneThirdOrValidBlock

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-06 21:10:26 +00:00
Raul Jordan
dd3ac6c2ed DB Migration for Optimal Local Slashing Protection (#8212)
* begin migration logic

* wrote migration logic

* begin test file

* test for migration working

* gaz

* progressutil

* migration works even if partial data was written
2021-01-06 20:41:31 +00:00
Radosław Kapka
9b3e1eb643 Implement GetHealth in the node API (#8217)
* Implement GetHealth in the node API

* repair fuzz mock

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-06 20:11:20 +00:00
Victor Farazdagi
da59fdd22b Attestation Aggregation: optimize attestation list validation (#8213)
* optimize candidate validation on att aggregation

* restore test

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-06 19:26:19 +00:00
Shay Zluf
f014374de2 Move attestation protection call after signing (#8216)
* Move validator protection after signing

* fix tests

* remove unused code
2021-01-06 11:41:00 -06:00
Radosław Kapka
392e61fbee Revert changes to sync service status check (#8215) 2021-01-06 11:19:53 +00:00
Radosław Kapka
7135a8542f Check if initial sync service has been initialized (#8214) 2021-01-06 10:45:22 +00:00
Raul Jordan
c354871762 Optimal Local Slashing Protection DB Schema (#8211)
* add new approach for slashing protection

* benches

* tests passing

* gaz

* all tests passing

* comment
2021-01-06 03:04:46 +00:00
Radosław Kapka
bc2cd29d4b Implement GetVersion in the node API (#8207)
* initial implementation

* implement GetVersion

* remove implementation of GetIdentity

* remove MetadataProvider from server

* gzl
2021-01-05 21:06:51 +00:00
terence tsao
023e258f6a Stream verified block (#8206) 2021-01-05 12:40:11 -08:00
Victor Farazdagi
9d737d60f4 Declare err in loop to limit its scope (#8200)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-05 13:55:23 +00:00
Victor Farazdagi
1abe92fd8b Remove redundant parentheses around nil values (#8199)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-05 13:29:46 +00:00
Victor Farazdagi
e5c69bd387 Add space at the start of comments (#8202)
* add space at the start of comments

* undo case change
2021-01-05 13:09:41 +00:00
Victor Farazdagi
318f83957a Fix data races in tests accessing beacon config concurrently (#8190)
* add mutex to params/config

* split config files into test/prod

* add tags checker

* add regression test

* remove debug info

* update bazel config

* go fmt

* make sure that conditional file is kept by gazelle

* update build tag: test -> develop

* gazelle

* remove redundant import

* fix data race in TestService_ReceiveBlock
2021-01-05 04:51:25 +00:00
Raul Jordan
f67f8dd6df Configurable Interval for Debouncing Keystore Reloading in Validator Client (#8149)
* configurable keystores debounce interval

* use a time duration flag instead

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-05 00:52:12 +00:00
Jeff Widmer
0e5da504f4 Fix for prysm.bat issue 'Validator' is not recognized as an internal or external command (#8097)
Fix for the issue where if either the beacon, validator, or slasher are already up to date, then the message:
"'Validator/Beacon/Slasher' is not recognized as an internal or external command, operable program or batch file."
The issue was that the message  "Validator/Beacon/Slasher is up to date." is not echoed to the console but it is trying to be run as a command.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-04 23:27:38 +00:00
Cipio
f6af79f415 Fix file permission checks for Windows (#8164)
* Does bitwise compare for MKDIR

* Implemented a more global solution to windows permission issues

* Remove unneeded line I added earlier.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-01-04 22:48:42 +00:00
Radosław Kapka
af2c36ec40 Add names to certain return values in accounts (#8159)
* add names to certain return values

* remove redundant

* rename selected public keys

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 21:44:15 +00:00
terence tsao
5dc8eb45d3 Add slot in epoch field for `Attestation schedule..." log (#8166)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 21:10:32 +00:00
Victor Farazdagi
b54743edbf Add mutex to params/config (#8160)
* add mutex to params/config

* split config files into test/prod

* add tags checker

* add regression test

* remove debug info

* update bazel config

* go fmt

* make sure that conditional file is kept by gazelle

* update build tag: test -> develop

* gazelle

* remove redundant import

* update deps.md (per Nishant's suggestion)

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 20:48:39 +00:00
Victor Farazdagi
04b2e0776d Fix import shadowing of state package (#8191)
* update shadowed var name

* update var names

* remove unnecessary delta

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 20:07:12 +00:00
Shay Zluf
70da296a3b Bring back disable slashing broadcast flag (#8141)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 19:36:17 +00:00
Mohamed Mansour
2defff0886 Add new GetVersion API to Health Service (#8167)
* Add new GetVersion API to Health Service

This is to support showing version information in the web ui.
Since health.go is built through validator bazel, we can use
`shared.GetVersion` directly.

Backend for: prysmaticlabs/prysm-web-ui#107

* Run goimports and update-go-pbs

* go mod tidy

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-01-04 18:51:52 +00:00
Victor Farazdagi
ee8aacbbbf Remove redundant lambda around cleanup code (#8192)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 18:16:18 +00:00
terence tsao
4055841952 Update int -> string conversion to make go test happy (#8183)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 17:53:59 +00:00
terence tsao
bf673ecb12 Validator nil duty should not panic (#8171)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-01-04 17:28:00 +00:00
Victor Farazdagi
7c25d5c852 Compare strings using strings.EqualFold() (#8193) 2021-01-04 16:46:22 +00:00
Raul Jordan
4c6e0c5f46 Update Prysm Web UI to Beta.3 (#8163)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-18 23:25:48 +00:00
Raul Jordan
768994550c Fix Unknown Validator Edge Case in ListValidatorBalances (#8162)
* ensures unknown validators do not mess up rest of api response

* rem old test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-18 22:51:44 +00:00
Victor Farazdagi
f038d782c2 Fix issue with custom chain/network ID configuration (#8147)
* move chain/network id to beacon config

* go fmt

* improve tests

* validator params

* update deposit contract address

* complete tests

* re-arrange comments

* Less mis-leading comment, per Terence's review

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-18 22:22:48 +00:00
terence tsao
ff64fdcfb5 Flag to enable duty count down (#8161)
* Add a flag to enable count down

* Add tests
2020-12-18 21:12:57 +00:00
Victor Farazdagi
d8c31b79df Fix import shadowing of db package (#8158)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-18 19:12:30 +00:00
Nishant Das
ea88799585 Revert Inbound Peer Limit (#8155)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-18 18:33:31 +00:00
Raul Jordan
72dc43989f Stream Validator and Beacon Logs via gRPC Streams (#8150)
* implement validator logs stream

* fix test

* tidy

* proto regen

* add logs stream to the beacon node

* beacon logs working

* impl

* pass test

* gaz

* rem lock

* fix space
2020-12-18 18:03:24 +00:00
Victor Farazdagi
e772e8c8c2 Init sync: minor style fixes (#8156)
* simplify FSM calls

* improve calculateHeadAndTargetEpochs API

* simplify

* simplify nil assignment
2020-12-18 14:31:15 +00:00
terence tsao
df93affb4e Move hot state cache to stategen (#8153)
* Move hot state cache to stategen

* Fix build.bazel

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-17 20:40:47 +00:00
Raul Jordan
d19c57cdb6 Remove Logout from Validator RPC Authenticated Paths (#8151)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-17 19:46:27 +00:00
terence tsao
756ccbe5e4 Update Attestation schedule... log for clarify (#8148)
* Don't use fraction, use different fields

* Update validator/client/validator.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Go fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-17 19:12:41 +00:00
Nishant Das
46c67f1e9e Fallback To Historical Sync For Powchain (#8146)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-17 18:49:22 +00:00
Nishant Das
44c3adb367 Add Public Method To Retrieve Discovery Address (#8143)
* add method

* fix

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-17 18:03:18 +00:00
Radosław Kapka
25b151ab78 Make TLS mandatory by default when unmarshalling remote wallet options (#8133)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-12-17 16:59:27 +00:00
Raul Jordan
f75b8a3be1 Implement Unified Validator API Endpoints for Beacon Chain Information (#8139)
* define all endpoints

* wrapper

* implement required validator endpoints

* begin impl

* implement remaining endpoint

* imports

* add in list validators

* intercepter

* test added
2020-12-17 16:26:32 +00:00
Nishant Das
dfdf77cb95 Add Instead of Subtract in Epoch Boundary Check (#8145)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-12-17 14:31:05 +00:00
Radosław Kapka
d5bf8376c2 Clean up account logs and errors (#8142)
* small fixes in logs and errors

* fix error message in test

* found a period hiding in an error message

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-17 13:37:06 +00:00
Nishant Das
e2d7ec6f97 Refactor Method Signatures For Powchain (#8110)
* checkpoint

* fix tests

* fix visibility

* fix

* victor's review

* remove redundant LF

* remove redundant LF

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-12-17 12:33:34 +00:00
Raul Jordan
d650034734 Lock Only When Needed When Fetching Attesting History (#8140)
* lock when needed in attesting history

* rw
2020-12-17 00:18:38 +00:00
Preston Van Loon
a7cf77fc26 Update rules docker to include https://github.com/bazelbuild/rules_docker/pull/1666, which updates the base images (#8136)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-16 14:56:38 -06:00
terence tsao
0dcbf177aa Fix participation query returning balances of orphaned chain (#8137)
* Check if block is canonical

* Add tests and better comments

* Grammar

* Update test for nil state
2020-12-16 13:31:34 -06:00
Nishant Das
82bba593eb Do Not Verify Attestations When Packing Them (#8135)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-16 18:06:49 +00:00
Raul Jordan
148e7fcd59 Consolidate Required Web UI Endpoints Into Single Protobuf File (#8127)
* define required endpoints for unifying backends

* proto definitions

* impl

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-16 17:30:48 +00:00
terence tsao
20dede7532 Move state summary cache to DB (#8101) 2020-12-16 08:56:21 -08:00
Preston Van Loon
3fb49433a1 Limit prometheus requests in flight, set timeout to reasonable 30 seconds (#8130) 2020-12-16 04:57:02 +00:00
Preston Van Loon
4326cbbf08 Validator database: use snappy compression on encoded attestation history (#8129)
* Remove old buckets, rename new buckets to be canonical

* Add migration and test

* Do the migrations

* Gazelle

* Clearify code, code review

* gofmt
2020-12-16 03:33:04 +00:00
terence tsao
dc27cd7a1e Pass context to NewKVStore (#8125)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-15 22:07:01 +00:00
terence tsao
0449cd3450 Allow update cache at last slot of the epoch (#8094)
* Epoch boundary updates at the last slot of the epoch

* Report metric on first slot

* Remove comment

* Add locks to param config

* Remove lock for copy

* Revert "Add locks to param config"

This reverts commit 79d5130b58.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-15 21:19:02 +00:00
terence tsao
6244163770 FC test coverage improvement (#8120)
* Test coverage improvements

* Gazelle

* Update namings

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-15 20:44:35 +00:00
Victor Farazdagi
f5c87075f2 Fix issue with roaming data dir on Wins (#8095)
* patch beacon node

* make sure that check is executed before anything else

* fix format

* make sure that check is reusable by other executables

* debug infor

* fix typo

* more debug info

* use copydir

* cleanup

* better explanation

* gazelle

* go fmt

* debug tos permissions

* upadte copydir

* gazelle

* better check of tos acceptance

* expand path

* update validator

* move fixing func

* move fixing method

* make sure that updater works both on main and subcommands

* remove from startnode

* add copydir test

* add DirFiles method and tests

* fix test

* add and test HashDir

* update tests

* fix test

* add datadir removal

* update messages

* further update messages
2020-12-15 14:01:51 -06:00
Preston Van Loon
ad7d3c74cc Validator DB cleanup: remove obsolete buckets (#8122) 2020-12-15 18:24:56 +00:00
Nishant Das
508c5fcf2f More Efficient Validation of Proposer Index (#8107)
* metric

* make it better

* make it better

* gaz

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-15 16:27:05 +00:00
Victor Farazdagi
a0c475671c Add extra methods to shared/fileutil (#8117)
* add extra methods to fileutil

* Shay's suggestion

* Update shared/fileutil/fileutil.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>

* Adds reference to the original implementation

Co-authored-by: Shay Zluf <thezluf@gmail.com>
2020-12-15 14:18:15 +00:00
Preston Van Loon
72a92fe708 CI: Disable remote caching of GoStdLib (#8111)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-15 05:58:52 +00:00
terence tsao
6a5589f99e Skip proposer indices cache update if exists (#8096)
* Check if cache is empty before update

* Add tests

* Fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-15 00:09:30 +00:00
terence tsao
70c0bb106b Beacon node code health improvements (#8109)
* Apply code health fixes after code inspect

* Remove attestationRoot

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-14 23:41:24 +00:00
Victor Farazdagi
0f18867f08 Remove duplicate package imports (#8104)
* remove duplicate imports

* remove unused lookupLimit

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-14 22:22:55 +00:00
Cipio
630d57377a Fix Slasher Backup DB panic on call. (#8099) 2020-12-14 21:39:26 +00:00
terence tsao
3e9d721280 Validator code health improvements (#8106) 2020-12-14 21:10:02 +00:00
Steven Allen
2428880058 Update go-libp2p to 0.12.0 (#8015)
* Update go-libp2p to 0.12.0

go-libp2p 0.12.0 made some significant changes to the stream interfaces around
stream closing:

* Close now closes in both directions and frees the stream. However, unlike
FullClose did, it doesn't _wait_ for the remote peer to respond with an EOF.
* To close for writing, call CloseWrite (like one would on a TCP connection, etc.).

This patch:

* Replaces calls to FullClose with Close where appropriate.
* Replaces calls to Close with CloseWrite where appropriate.
* Removes redundant Close calls.
* Calls Reset to where appropriate to indicate that the request/response was
  aborted. Unlike Close, this will not flush and will not cause the remote peer
  to read an EOF. Instead, the remote peer will read an ErrReset error.
* Ensures we always either close or reset streams. Send wasn't closing the
  stream on some error paths.
* Now that stream closing is async, we explicitly wait for a response when
  "hanging up" on a peer (so we don't hang up before they receive our
  response/goodbye message).

* update bazel

* Gazelle

* revert unintentional bazel workspace change

* appease an overzealous linter

* update to latest

* Refactor encoder

* gazelle

* Gazelle

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-14 17:22:25 +00:00
Potuz
4d1f01aacc Change block_arrival_latency buckets to exponential format (#8065)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-12-14 16:00:07 +00:00
Victor Farazdagi
b9848dc94f Remove unused vars in tests (#8103)
* update process_block_test

* service_attester_test

* update service and rpc_status tests

* go fmt
2020-12-13 05:23:13 +00:00
Nishant Das
579335f81a Remove Saving Of Target And Source Epoch (#8102)
* remove

* skip
2020-12-13 04:26:18 +00:00
Nishant Das
11bbf06d03 Add Inbound Peer Limit (#7942)
* add changes

* fix up

* fix

* add test

* fix test

* fix again

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-12-12 03:46:55 +00:00
Nishant Das
29804fa572 Refactor Subnet Search (#8048)
* checkpoint progress

* checkpoint

* clean up

* do better

* fix test

* fix

* fix

* preston's review

* fix

* fix

* fix

* add iterator

* go doc

* make it a config parameter

* Apply suggestions from code review

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-12-11 18:40:56 -08:00
Radosław Kapka
4ec396c025 Refetch validating keys if no keys are fetched (#8000)
* refetch validating keys every 30 seconds

* deduplicate error/log messages

* remove redundant break statement

* comment about execution flow

* move code to wait_for_activation.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-12-11 20:55:52 +01:00
Raul Jordan
1fbfd52e52 Simpler and Safer Attester Slashing Protection (#8086)
* att sign validations

* eliminate old cached methods and use a simple approach in the db

* redefined db methods

* db package builds

* add multilock to attest and propose

* gaz

* removed concurrency tests that are no longer relevant

* add cache to db functions for attesting history checks

* passing

* add in feature flag --disable-attesting-history-db-cache

* remove lock

* Revert "remove lock"

This reverts commit b1a65020e4.

* comment

* gaz
2020-12-11 12:31:35 -06:00
Mohamed Mansour
2e18df642d Expand Validator Input Errors (#8090)
The reason of why a validator input was failing was very generic,
this allows the actual implementation to state why it failed by
passing the exception forward.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-11 10:57:47 -06:00
Nishant Das
99b3835f19 Add Fallback Option for Eth1 Nodes (#8062)
* fix

* fix tests and change back

* gaz

* change

* ready again

* Update beacon-chain/flags/base.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>

* radek's review

* Update shared/cmd/helpers.go

* Update shared/cmd/helpers_test.go

* Update shared/cmd/helpers_test.go

* Endpoint/endpoint

Co-authored-by: Shay Zluf <thezluf@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2020-12-11 19:15:04 +08:00
Victor Farazdagi
46d99fdc00 Attestation aggregation: remove proper set duplicates (#8063)
* fix proper-set issue

* move test into dedicated test file

* move functionality from maxcover -> proposer

* adds dedup to proposer

* fix tests

* update tests

* remove redundant proper subset test

* fix bug with identical expression
2020-12-11 11:13:14 +03:00
Preston Van Loon
923e4d3a5e Attempt to reconnect when waiting for activation (#8057)
* Attempt to reconnect when waiting for activation

* rm fuzz/attestation_fuzz.go

* math.Min, not math.Max

* Gofmt

* resolve RVV-B0003
2020-12-10 19:26:31 -06:00
terence tsao
bb9e2ba12c Validator client logs time left to next duty (#8088) 2020-12-10 10:56:18 -08:00
Preston Van Loon
f44b2a35e4 Update waiting validator methods to be context aware (#8078)
* Update waiting validator methods to be context aware

* Enable debug logging for validator in e2e

* invert logic in deferred function, remove for loop

* return early if wait is 0 or less

* overwrite ctx

* t.Stop() chan closure is hanging. Doesnt make sense, so ignoring that cleanup task. It shouldnt happen at runtime anyway

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-12-10 10:00:48 -06:00
terence tsao
00dacbd00d Remove custom block body root and block root methods (#8069)
* Remove custom block body root and block root methods

* Add nil checks and fix tests

* Fmt

* Typo
2020-12-09 12:11:42 -06:00
Radosław Kapka
92736d0188 warn when creating an imported wallet (#8081) 2020-12-09 16:41:26 +01:00
Preston Van Loon
c96db1a122 Add spans to pre and post att signing updates (#8079)
* Add spans to pre and post att signing updates

* span on db method

* Add span to isNewAttSlashable
2020-12-08 23:47:02 -06:00
terence tsao
c5770a2e56 Add beacon block nil body checks (#8077)
* Add nil checks and fix tests

* Gaz

* Revert one minor typo

* Update test

* Remove extra space
2020-12-08 16:27:58 -06:00
terence tsao
ade3b2f2df Add state field count to config (#8068)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-07 21:49:28 -06:00
Radosław Kapka
9d7052796b Restore database CLI command (#8061)
* restore beacon node db

* revert image name

* move restore out of the kv folder

* remove files from kv folder

* go mod tidy

* Remove usage of prometheus testutil

* add yes/no to prompt text

* restore slasher db

* organize imports

* go mod tidy

* restore validator db

* close slasher db

* defer close backup db in tests

* simplify function literal
2020-12-07 21:36:43 +01:00
Shay Zluf
fbbdd94fea Resolve panic on shutdown with offline eth1 node (#8033)
* Resolve panic on shutdown with offline eth1 node

* Move fix tne right place nishant feedback

* fix log message

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-12-07 10:16:23 +00:00
Victor Farazdagi
b51aec6981 Init sync: minor fixes (#8060)
* fixes typo

* simplify code
2020-12-07 09:33:06 +00:00
terence tsao
b4437e6cec Load graffiti from file (#8041)
* Pass graffati file and   use it

* Visibility

* Parse test

* More proposal tests

* Gazelle

* Add sequential functionality

* fix length check

* Update priorities. Specified -> random -> default

* Log warn instead return err

* Comment

* E2e test

* Comment

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-12-04 23:15:12 +00:00
Arthur Burkart
8ad328d9b3 fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs

# What

Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.

Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.

# Testing

This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:

```go
package main

import (
	"log"
	"os"
	"strings"

	"github.com/davecgh/go-spew/spew"
	"github.com/urfave/cli/v2"
)

type Config struct {
	GrpcHeadersFlag string
}

func main() {
	app := &cli.App{
		Action: func(c *cli.Context) error {
			for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
				if hdr != "" {
					ss := strings.Split(hdr, "=")
					spew.Dump(ss[0])
					spew.Dump(strings.Join(ss[1:], "="))
				}
			}
			return nil
		},
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "grpc-headers",
				Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
					"calls. Example: --grpc-headers=key=value",
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}
```

Example invocation:

```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```

* Adds tests to new gRPC header parsing code

* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
Victor Farazdagi
21ede7634e Attestation aggregation: maxcover vs naive aggregation effectiveness test (#8043)
* maxcover performance test

* gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-04 17:24:57 +00:00
Victor Farazdagi
57b74283d3 Attestation aggregation: removes redundant code from max-cover benchmarks (#8044)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-04 16:51:31 +00:00
Victor Farazdagi
be078d6a16 Update TestMain(): do not call os.Exit() explicitly (#8046)
* update workspace

* update testmain
2020-12-04 16:10:07 +00:00
Victor Farazdagi
ccba8cfa5a Update rules_go to v0.24.9 and golang to v1.15.6 (#8045) 2020-12-04 15:28:03 +00:00
Victor Farazdagi
afbfaedea4 Unskip fixed init-sync service test (#8042) 2020-12-04 11:57:46 +00:00
terence tsao
3ce96701de Update attestation schedule log with total attester count (#8013)
* Log attesting total

* Use the right library

* Go fmt

* Use fmt

* No space is better

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-04 07:02:58 +00:00
simonatsn
d2ba45aad9 Update blst to v0.3.1 and incorporate subgroup changes (#7971)
* Update blst to v0.3.1 and incorporate subgroup changes

* go mod tidy

* gofmt

* Update bzl blst dependency

* Remove unnecessary check for nil

* Run bazel run //:gazelle -- fix

* Update blst to v0.3.2

* fix sha

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-04 06:46:08 +00:00
Raul Jordan
14e1f08208 Add Backup Webhooks to All Prysm Services With DBs (#8025)
* integrate backup webhooks

* pass slasher tests

* fix node

* cmd

* gaz

* read test passes

* radek feedback

* added comment

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-12-03 22:28:57 +00:00
Victor Farazdagi
647b4cf108 Round robin: half open interval in syncToFinalizedEpoch (#8039) 2020-12-03 21:55:42 +00:00
terence tsao
c090c6a1c5 Revert "Logging with PadLevelText to true" (#8036)
This reverts commit c51754fa8a.

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-03 20:38:00 +00:00
Victor Farazdagi
7dd0c24fea Skip bogus init-sync test (#8038) 2020-12-03 20:20:04 +00:00
Victor Farazdagi
e1755b6066 Invert enable-sync-backtracking (#8034)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-03 15:43:26 +00:00
Victor Farazdagi
3092f75ec2 Init sync: conditional syncing to finalized slot (#7999)
* extract sync methods

* add unit test

* gazelle

* Update beacon-chain/sync/initial-sync/round_robin.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>

* better set back step

Co-authored-by: Shay Zluf <thezluf@gmail.com>
2020-12-03 14:10:51 +00:00
Shay Zluf
821620c520 Add test for local protection genesis attestation (#7977)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-03 01:02:51 +00:00
Victor Farazdagi
5417e8cf31 Init-sync: enable peer scorer by default (#7974)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-03 00:45:20 +00:00
Radosław Kapka
323769bf1a Make TLS connections to a remote wallet non-mandatory (#7953)
* disable-remote-signer-tls flag

* use flag in edit-config

* send requests without TLS

* change warning message

* fix account list output test

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-03 00:18:15 +00:00
terence tsao
c51754fa8a Logging with PadLevelText to true (#8003)
* Use logrus formatter with pad

* Validator

* Fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-02 23:49:13 +00:00
terence tsao
2153a2d7c3 Remove logging deposit inclusion slot (#8023)
* Remove logging deposit inclusion slot

* Remove old tests

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-02 21:17:47 +00:00
Nishant Das
20514cd97f Fix Interop Mode (#7978)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-12-02 20:29:36 +00:00
Victor Farazdagi
32f6bfd0a5 update deprecated multiaddr package (#8022) 2020-12-02 11:21:43 -08:00
Victor Farazdagi
c7f7a29d7e remove redundant start slot (#7991)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-02 20:47:39 +03:00
Nishant Das
387f7b28c1 Add Buffer For Inbound Peers (#8018)
* allow inbound peers

* comment

* gaz

* gaz

* Update deps.bzl

Co-authored-by: Shay Zluf <thezluf@gmail.com>

* add test

* re-arrange imports

* fix up

* fix tests

* gaz

* Update beacon-chain/p2p/service_test.go

* fmt

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Shay Zluf <thezluf@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-12-02 10:45:28 -06:00
terence tsao
cf3181e2de Update README to include branching strategy (#8006)
* Update README.md

* Update README.md

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-12-02 09:48:52 -06:00
Mohamed Mansour
9d2fe80140 Fix missing space in error message in account list (#8009)
When validating account list, there was a missing space. This fixes that nitpick.

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-12-02 16:02:59 +03:00
Shay Zluf
f9c696ed54 Pending block queue lock fixes (#8002)
* Unlock in case of error

* fix comment

* fix comment

* revert one defer

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-12-02 11:50:37 +02:00
Raul Jordan
3bd5e58a5c Merge branch 'master' into develop 2020-12-01 08:06:16 -06:00
Raul Jordan
fc7c6776f6 Create Bucket If Not Exists When Fetching Proposal History (#8011)
* create bucket if not exist when fetching proposal history

* adding unit test
2020-12-01 08:00:03 -06:00
Potuz
9a1423d62d Log with field error instead of err (#7998) 2020-12-01 05:38:42 -08:00
Nishant Das
a13de7da11 Remove Exclusion List (#7992)
* remove

* gaz

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-01 02:17:29 +00:00
Raul Jordan
01bf97293f Fix Miscellaneous Deep Source Issues (#8007)
* deep source fixes

* sh fixes

* fix import

* test err

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-11-30 19:55:30 -06:00
terence tsao
645931802f Improve genesis event log and load blocks to fork choice log (#7946)
* Update a few logs

* Go fmt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-12-01 00:06:16 +00:00
terence tsao
ea10784a4a Validator logging: return early if no att included (#7979)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-30 23:28:12 +00:00
terence tsao
3af7809964 Save cached state summaries on Stop() (#7988)
* Save cached state summaries on Stop()

* Fixed test and added one more test
2020-11-30 17:08:23 -06:00
terence tsao
b150acffca Recover state summary for sync validation (#7994)
* Recover state summary

* Add test

* Fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-29 20:42:45 -06:00
Victor Farazdagi
54a42ce4a8 more robust processing of invalid head slot (#7990) 2020-11-29 15:03:25 -06:00
Raul Jordan
9d174d5927 Add Support for Prysm Web V1.0.0-beta.1 (#7983)
* new web release

* site data update, add /logs to logs endpoints

* tests fixed

* test

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-27 20:30:12 +00:00
terence tsao
1b1b36497f Add validator bolt db metric collector (#7982)
* Validator db: add metrics collector

* Use the right library

* Go fmt

* Fix tests
2020-11-27 20:03:44 +00:00
Raul Jordan
04615cb97b Add Validator RPC Endpoint to Retrieve Beacon + Validator Logs Websocket Endpoints (#7981)
* add logs endpoint

* commands to retrieve logs endpoints

* ensure works at runtime

* add auth
2020-11-27 18:28:45 +00:00
terence tsao
b243665d3e Save lowest source and target epochs in post (#7973)
* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

* Save lowest epcohs at post signature update

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-26 19:58:20 +00:00
pinglamb
654ef1afe5 Added flag for specifying header request limit (#7896)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-26 18:38:52 +00:00
Preston Van Loon
0dbf5c4e63 Increase public key cache size for Pyrmont (#7967)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-26 18:04:18 +00:00
terence tsao
c456dcdce8 Replace highest with lowest for signed epoch DB methods (#7965)
* Replace highest with lowerest

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* Invert equality for saveLowestSourceTargetToDB

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-26 17:35:36 +00:00
Raul Jordan
10857223d0 Delete Dead Code in the Validator Client's Database Package (#7970)
* delete deprecated

* mod

* deep source

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-26 16:50:55 +00:00
Nishant Das
4ef8a0f99e Update Geth Again (#7968)
* fix again

* tidy up
2020-11-26 09:52:27 -06:00
Raul Jordan
af0977b8d0 Implement Export Block Proposals (#7964)
* export funcs for proposals

* add failing test

* round trip test passes

* progress

* deepsource

* Update validator/slashing-protection/local/standard-protection-format/export.go

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

* Update validator/slashing-protection/local/standard-protection-format/import.go

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

* revert

* empty root

* deep source

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-26 04:09:35 +00:00
terence tsao
528272fc66 Add Getters/Setters in ValidatorDB For Highest Signed Source and Target Epochs (#7961)
* Add getters and setters for source and target epochs

* Use the correct ImportStandardProtectionJSON

* Add tests

* Fix buckets

* Fix source to target

* Update validator/slashing-protection/local/standard-protection-format/import.go

* Fix bytesutil.BytesToUint64BigEndian will return 0 if input is less than 8 bytes

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-26 02:39:23 +00:00
Raul Jordan
c5c868d0a6 Use Separate Buckets to Store Special Data for Proposal Slashing Protection (#7963)
* ignore keys in the schema

* add test

* use separate buckets for special values where pubkey is the index

* test fix
2020-11-25 23:58:01 +00:00
terence tsao
622ab94465 Move Verified and saved pending attestations to pool to debug (#7928)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 22:52:57 +00:00
Raul Jordan
ae8a619775 Allow Optional Signing Roots in Proposal History (#7960) 2020-11-25 22:24:07 +00:00
Raul Jordan
36b1eb66d5 Add Attested and Proposed Public Keys DB Methods (#7959)
* add attested and proposed pubkeys methods

* Update validator/db/kv/attestation_history_v2.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 21:37:39 +00:00
Nishant Das
639dcb028c Fixing Validator Config (#7940)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 20:40:18 +00:00
Raul Jordan
edb40ddea4 Add ValidatorDB Methods for Highest and Lowest Signed Proposals (#7957)
* add in highest and lowest signed proposal

* begin adding tests

* add in db tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 20:04:43 +00:00
Preston Van Loon
0d2e3d978c Delete VERSION (#7958)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 19:20:57 +00:00
Preston Van Loon
29c6a0c42c Fix zero genesis check, make processAttestation routine wait for genesis time to be set (#7947)
* Fix zero genesis check, make processAttestation routine wait for genesis time to be set

* Update beacon-chain/blockchain/receive_attestation.go

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-25 18:52:59 +00:00
Nishant Das
aefa3e191a Check Sync Status First (#7895)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-25 18:27:27 +00:00
Preston Van Loon
987205afc6 Update security.txt (#7956) 2020-11-25 17:38:35 +00:00
dv8silencer
3ae4b793e6 Improve error log for when database network conflicts with runtime network (#7945)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-25 05:15:30 +00:00
terence tsao
600427bdb0 More bootnodes (#7948) 2020-11-25 04:25:47 +00:00
terence tsao
c7dd33431f Add lighthouse bootnodes (#7943)
* Add lighthouse bootnodes

* Remove extra line
2020-11-24 18:03:28 +00:00
Shay Zluf
0cf9800b75 Fix locks and fallback to db read if attestation history map is missing a pub key data (#7937)
* minimal change to handle nil attesterHistoryByPubKey

* Revert "Always Update Attesting History If Not Slashable (#7935)"

This reverts commit 3cc2ebc5d5.

* remove unused functions

* move save before propose

* wait before go func

* move wait into the go routine

* handling map mutation

* remove map handling in this case

* log in case it is still not found

* fix log

* fix locks

* Update validator/client/attest_protect.go

* remove code duplication

* remove method extraction

* move metrics to their appropriate place

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-11-24 11:24:23 -06:00
Raul Jordan
3cc2ebc5d5 Always Update Attesting History If Not Slashable (#7935)
* update attesting history always if not slashable

* initialize empty if no history found

* rem duplicate logic
2020-11-24 02:48:20 +00:00
Raul Jordan
2cb814648a Improve Slashing Protection for V1, More Tests and Observability (#7934)
* tests tests and more tests

* tests all passsss

* log for double vote
2020-11-23 19:03:04 -06:00
Raul Jordan
dc897a2007 Optionally Save Wallet Password on Web Onboarding (#7930)
* persist wallet password to wallet dir if onboarded via web

* add flag

* gaz

* add test

* fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-23 22:11:42 +00:00
terence tsao
a051e684ae Update log levels (#7931) 2020-11-23 13:16:08 -08:00
Radosław Kapka
64be627a6d Make grpc-headers flag work (#7932) 2020-11-23 20:38:32 +00:00
Nishant Das
6f766ed583 Exit Pending Queue Properly (#7927)
* exit properly

* terence's review

* Update beacon-chain/sync/pending_blocks_queue.go

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

* Update beacon-chain/sync/pending_blocks_queue.go

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

* fix tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-23 19:34:40 +00:00
Raul Jordan
b0dfc46603 Fix Up READMEs for Mainnet (#7910)
* fix up readmes

* Update README.md

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

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-23 18:47:55 +00:00
Nishant Das
8c3faaa4c7 Add Back Error/Debug Logs (#7922)
* add back logs

* add back string

* Reformat loggings

Co-authored-by: Terence Tsao <terence@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-23 18:29:27 +00:00
Nishant Das
4c0db8bca4 Bake In Mainnet Bootnodes (#7925)
* add in bootnodes

* fix teku's bootnode
2020-11-23 17:19:35 +00:00
Raul Jordan
0c5c246ee7 Prysm Web V1 Release (#7921)
* even more cors

* auth fixes for web v1

* ensure web works

* include web ui v1 release

* new site data

* fmt

* test

* tests pass

* gaz

* build fix

* no ssz

* unused type

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-23 06:29:58 +00:00
dv8silencer
f871e1f3ef Give error message if trying to import into non-imported wallet (#7913)
Co-authored-by: dv8silencer <15720668+dv8silencer@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-23 04:08:07 +00:00
Preston Van Loon
658dd95313 Add teku's bootnode (#7919)
* Add teku's bootnode

* Ignore mainnet config for TODO check
2020-11-23 01:20:55 +00:00
Preston Van Loon
57fe012bc2 P2P: Increase outbound message queue size to 256 (#7916) 2020-11-22 23:54:58 +00:00
Raul Jordan
d62420b940 More Default CORS Rules (#7915)
* even more cors

* terence feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-22 23:10:21 +00:00
Preston Van Loon
11bbea2562 Use params network config as default bootstrap nodes and deposit contract (#7904)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-22 21:22:44 +00:00
terence tsao
2172cd60a6 Update sync loggings (#7914) 2020-11-22 14:31:55 -06:00
Raul Jordan
2a546cc50b Remove Deprecated Tooling (#7912)
* remove old tools

* tidy and gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-22 19:07:02 +00:00
terence tsao
7d0031ee77 Update boot node to not use pyrmont (#7906)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-11-22 18:47:23 +00:00
pinglamb
acf49fb38f Fix Alpine Docker Image (#7883)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-11-22 18:04:13 +00:00
Raul Jordan
26658a9f1f Add More Default CORS Domains to the gRPC Gateway (#7901) 2020-11-22 17:12:24 +00:00
Nishant Das
60d99c83eb fix pending queue (#7899) 2020-11-22 08:42:27 -08:00
Alon Muroch
98557e8f5e highest slashing attestation RPC endpoint (#7647)
* highest slashing attestation RPC endpoint

* slasher mock fix

* Update proto/slashing/slashing.proto

Co-authored-by: Shay Zluf <thezluf@gmail.com>

* comments + small fixes

* PR review ctx comments and fixes

Co-authored-by: Shay Zluf <thezluf@gmail.com>
2020-11-22 08:51:20 +00:00
Preston Van Loon
1ba747b3c9 Change log from ERROR to DEBUG (#7892) 2020-11-21 23:14:19 -08:00
1736 changed files with 138588 additions and 61547 deletions

View File

@@ -17,9 +17,12 @@ test --host_force_python=PY2
run --host_force_python=PY2
# Networking is blocked for tests by default, add "requires-network" tag to your test if networking
# is required within the sandbox. This flag is no longer experimental after 0.29.0.
# Network sandboxing only works on linux.
--experimental_sandbox_default_allow_network=false
# is required within the sandbox. Network sandboxing only works on linux.
build --sandbox_default_allow_network=false
# Stamp binaries with git information
build --workspace_status_command=./scripts/workspace_status.sh
build --stamp
# Use mainnet protobufs at runtime
run --define ssz=mainnet
@@ -36,20 +39,17 @@ build --define kafka_enabled=false
test --define kafka_enabled=false
run --define kafka_enabled=false
# Enable blst by default, we use a config so that our fuzzer stops complaining.
build --config=blst_enabled
test --config=blst_enabled
run --config=blst_enabled
build --define blst_disabled=false
test --define blst_disabled=false
run --define blst_disabled=false
build:kafka_enabled --define kafka_enabled=true
build:kafka_enabled --define gotags=kafka_enabled
build:blst_enabled --define blst_enabled=true
build:blst_enabled --define gotags=blst_enabled
build:blst_disabled --define blst_disabled=true
build:blst_disabled --define gotags=blst_disabled
# Release flags
build:release --workspace_status_command=./scripts/workspace_status.sh
build:release --stamp
build:release --compilation_mode=opt
build:release --config=llvm
@@ -83,7 +83,7 @@ build:fuzz --linkopt -Wl,--no-as-needed
build:fuzz --define=gc_goopts=-d=libfuzzer,checkptr
build:fuzz --run_under=//tools:fuzz_wrapper
build:fuzz --compilation_mode=opt
build:fuzz --define=blst_enabled=false
build:fuzz --define=blst_disabled=true
test:fuzz --local_test_jobs="HOST_CPUS*.5"
@@ -237,3 +237,6 @@ build:remote --remote_timeout=3600
build:remote --experimental_remote_download_outputs=toplevel --experimental_inmemory_jdeps_files --experimental_inmemory_dotd_files
build:remote --remote_local_fallback
# Ignore GoStdLib with remote caching
build --modify_execution_info='GoStdlib.*=+no-remote-cache'

View File

@@ -2,7 +2,7 @@
# across machines, developers, and workspaces.
#
# This config is loaded from https://github.com/bazelbuild/bazel-toolchains/blob/master/bazelrc/latest.bazelrc
build:remote-cache --remote_timeout=3600
#build:remote-cache --remote_timeout=3600
#build:remote-cache --spawn_strategy=standalone
#build:remote-cache --strategy=Javac=standalone
#build:remote-cache --strategy=Closure=standalone
@@ -11,11 +11,18 @@ build:remote-cache --remote_timeout=3600
# Prysm specific remote-cache properties.
#build:remote-cache --disk_cache=
build:remote-cache --remote_download_minimal
build:remote-cache --remote_cache=grpc://bazel-remote-cache:9092
build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092
build:remote-cache --remote_local_fallback
# Enforce stricter environment rules, which eliminates some non-hermetic
# behavior and therefore improves both the remote cache hit rate and the
# correctness and repeatability of the build.
build:remote-cache --incompatible_strict_action_env=true
# Import workspace options.
import %workspace%/.bazelrc
startup --host_jvm_args=-Xmx1000m --host_jvm_args=-Xms1000m
startup --host_jvm_args=-Xmx2g --host_jvm_args=-Xms2g
query --repository_cache=/tmp/repositorycache
query --experimental_repository_cache_hardlinks
build --repository_cache=/tmp/repositorycache

View File

@@ -30,4 +30,4 @@ comment:
ignore:
- "**/*.pb.go"
- "**/*_mock.go"
- "**/testing/**/*"

View File

@@ -1,11 +1,17 @@
version = 1
exclude_patterns = [
"tools/analyzers/**",
"validator/keymanager/remote/keymanager_test.go",
"validator/web/site_data.go"
]
[[analyzers]]
name = "go"
enabled = true
[analyzers.meta]
import_paths = ["github.com/prysmaticlabs/prysm"]
[analyzers.meta]
import_paths = ["github.com/prysmaticlabs/prysm"]
[[analyzers]]
name = "test-coverage"
@@ -14,3 +20,7 @@ enabled = true
[[analyzers]]
name = "shell"
enabled = true
[[analyzers]]
name = "secrets"
enabled = true

View File

@@ -24,6 +24,12 @@ jobs:
uses: ./.github/actions/gofmt
with:
path: ./
- name: GoImports checker
id: goimports
uses: Jerome1337/goimports-action@v1.0.2
with:
goimports-path: ./
build:
name: Build
@@ -44,7 +50,7 @@ jobs:
- name: Build
# Use blst tag to allow go and bazel builds for blst.
run: go build -v --tags=blst_enabled ./...
run: go build -v ./...
# Tests run via Bazel for now...
# - name: Test

3
.gitignore vendored
View File

@@ -33,3 +33,6 @@ dist
# libfuzzer
oom-*
crash-*
# deepsource cli
bin

218
.well-known/security.pub Normal file
View File

@@ -0,0 +1,218 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFpZUO0BEAC/tqN6QctJKSOF+A7jrBzvNvs6rVEi9Hn55u/scKNIPkSRJRTy
8kVsDMha+EKXka8oQiVM+sHoHMIMCa3tdicm1/k5f67X8dqadQmFP4DhYRYIKCKT
TkntNG568ynf/yUs/YY9Ce8H17JvgytkLK50mxMxycUlYREMaRPMR8Wt1Arrd9QT
U0I2cZemeqUORKuiVuZjj/7BVDHvSXHvzpi5zKI86sJQTnzcuGqyNsrUU4n4sYrb
I+0TfEHzmSdxoAXSaMYjomPLmbaSdBiK/CeNKF8xuFCKJRd8wOUe5FcIN3DCdk0e
yoFye5RMC+W09Ro+tK/jTQ/sTUuNLJm0VUlddQQeoGlhQdLLwiU4PJqcyeL4KaN1
l8cVml7xr1CdemhGV4wmEqAgxnNFN5mKnS2KcDaHxRz7MoGNdgVVQuxxaE0+OsdJ
zCKtA12Q/OcR24qYVFg5+O+bUNhy23mqIxx0HiQ0DsK+IDvcLLWqta0aP9wd9wxG
eObh9WkCxELTLg8xlbe0d7R3juaRjBLdD5d3UyjqGh+7zUflMsFhpUPraNXdKzvm
AqT25cveadM7q/CNzFXeCwmKjZab8Jic8VB80KcikmX6y9eGOHwjFixBogxowlBq
3KpeNTqJMNHYBzEb0V18P8huKVO0SMfg11Z1/nU4NA4lcjiVImb5xnJS0wARAQAB
tCxQcmVzdG9uIFZhbiBMb29uIDxwcmVzdG9uQHByeXNtYXRpY2xhYnMuY29tPokC
NwQTAQgAIQUCWuZ7uwIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRBy4z5N
8aUDbtchD/4hQDTj7qsccQKpaL8furw+OWuoZtX38smO9LrcSoLaZlk5NRxFNlhQ
FaL6iyDLoDkWUXEPg94x1dMFBUfMdIuh6iEF2pcvCN6WG3Pd2j2kG6OxaIx+rI7a
eaD2Wds312etYATu+7AI6pxlQVqPeZi6kZVvXo8r9qzEnl1nifo7d3L4ut6FerDz
/ptvIuhW++BEgksILkwMA44U7owTllkZ5wSbXRJer0bI/jLPLTaRETVMgWmF5L2n
PWKhBnhBXf/P00zTHVoba0peJ/RGdzlb1JZH+uCQk0wGBl0rBMUmiihIB8DZBZDX
5prwMdoHG9qAT9SuJ8ZOjPKaBHVVVw4JOU6rX2+p9E49CVATsdoPfWVbNyVRGi5f
Oo0bJPZU3uO10Q09CIeyqT6JPDCZYS7po2bpfFjQTDkoIv0uPWOsV5l3cvFxVlcD
Pvir4669xhujmoVBOrp18mn/W/rMft2TJ84inp0seKSKdwBUeEyIZwwu1YTorFe4
bgJghDu/Y+K4y0wq7rpPimoiXSoJOaaIPrOzsKAVu20zJB4eoulXlPwHexix8wwf
xeVH4bGl3wtTFWKja0+EQVdxpt+uUlABvrheQbNlNGz5ROOAtjvwASI3YW/jVVaG
wSbOUuMEHfC1rSnj5Y9fN6FbilxJAZ2UbvZE6iXqqemfRdFuB5yedbQmUHJlc3Rv
biBWYW4gTG9vbiA8cHJlc3RvbjkwQGdtYWlsLmNvbT6JAjcEEwEIACEFAlqrvbMC
GwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQcuM+TfGlA269zg/9FynobfLE
Vh+Aid7l5C6pprHflHpdNVhdHzjvosLKfPMCcBJLyCLAIueKC0vvKbt5kyNV6Adl
6fibdO/vRrNsEdmKXTdfDnN03yVX+VO54rqyuweR09CbLHakECh5awWpk0x9E/Gc
3MlU8YDCVNPcWAw8JPZZ0y6s50/MFFXya+/opw45neH6WXrbqbIapzZ4V1bhkloF
TTz7LYp1dk6qjus/f1jHgujclJ6FazG+OqCpzJ22lnuwNYs8sv1DclW+lEUfIin5
PvzcSRCCd6NilFRSGzfBhM7wxZrAp0JzWXpM1jmd2WHtgErusTaTXRTATjPf9Chg
SE9UT3EJvJ5fPxuxm+qOAowpJwe8Irv+YuMzL8C6C2BhZIV8XID3/cErNeQbPocj
QFksmBEwpe9EG3Yhd5SmSXRhCtBFnyFKyOqPpAE2s+U0b7qsnWc50UFbIytPEm4C
YmdNL6IVilp/+LYFcRWWK/ppOtvtgbj8r7+Foidi/tCauJGt2BzhWH7DkLEdXGxk
PfR/rTgyuAQZowl03DaNwAPKegY2SIuROO9kpQACwTWZNg4l2yrZv09qrKBhohyn
b2i4pwHPZ5/bWLikdzENcJuvbH5qhf6tV0FIaNGbTkWX00uI++bvWAxxE25jZv56
e7VTaWuMt8Ly4DBcwl5JyWuvZ74+yv7QGp20WlByZXN0b24gVmFuIExvb24gKDB4
ZjcxRTlDNzY2Q2RmMTY5ZURGYkUyNzQ5NDkwOTQzQzFEQzZiOEE1NSkgPHByZXN0
b25AbWFjaGluZXBvd2VyZWQuY29tPokCNwQTAQgAIQUCWllQ7QIbAwULCQgHAgYV
CAkKCwIEFgIDAQIeAQIXgAAKCRBy4z5N8aUDbmvdD/4jkT1IXJyj65sgHus0HHYC
MBp6mzvtpDcPljg/5Nl1WXydv4zYGnEnIwWIqDYwwvokOKllxAjgevcplHqZa0cb
7XKCFk5h+56FLPHv9e0WK1fOFeo2ad3imNRstSHgaumGAWHJMg9vWbDisGv1zjQ0
usFkrMKoX34YzMt8KBD7IuQyeBkYNupT8EfByeA9Ta+wkvS+X6BojsFB1UWDAFCY
z8RgTcWIFjWtGZwIkWUKCzebqXbElpJF8ckZU9q4qVhyZ2DT+8BS/Lm0Sf4z6VTC
4EN10ZuN+F+J3DMR2Zuudp4X5OUGkDG4KuU/kvj6EJRWpbTS1D9ReK7hoApIbV72
Um6Mf7kC9EKvxgL1gOfl4aj3Io9M0R8FT/0WSMduQzf/jI3XqdNH0nYo2kTDdZm8
S972cyvt6frKYy6RsOlPz1+S61iCmupsRY+HyKDTa0vnpXg2c4dE1neF5eMI6SVw
viJvCG2cflctJ2PLiINZJYAg87gV5Rm1i/Lt2YG5zdxAXXJt2R0uuU9fv4DcHZLU
yx69Yuh+5UiEaXYU7xoRCdZJYyHbvaC2hPcDGnEa3K1QbgnI5hGAtG3cwdbYC5e3
bcaJb/LdwzkdRnHLgpxa/UTAIfejEI1U2kvVvNoe/HvEXq/OPrhFDvE4rW8AzbX+
ISTWWRY0lLSr8/SD0TDJMbkBDQRam2geAQgA0kESOibOO3CcXrHtqP9lPGmj6rVe
G18fRmPDJiWtx863QqJeByuuUKwrGkPW/sqtIa5Ano+iXVHpk7m955nRjBmz4gd8
xqSGZd9XpNObYPA5iirAO8ztpgQvuvsHH9y9Ge50NnR7hQSMUbGVeCUU/vljwT60
/U+UPnsTAmkhvkEI72x50l5Ih9ihcBcr5jJpi08XktE3sFOoannac0kZQJ6WXFrY
4ILbv8fVqcRf44xMKOlFB9qHhleGW0H9ZUjTKs9quRt7r5D1MOiwrZDjNN3LqMco
oWj37hb+3KkmIIsAYB2DjnWYkMPu2B0O4uSOHYAWfEJtRvA8qW7sWj+q1wARAQAB
iQIlBBgBCAAPBQJam2geAhsgBQkB4TOAAAoJEHLjPk3xpQNulz0P/2m9veAAGGCO
yPsqiNVVa8lrhmLGh/W+BaoszQ/r+pfin4xTOV5K5h3MC5CVJM0JxP/cxNol+Nmr
cYGbZgq4QhLlH6PdQ7cReL5ED6Wi+eHb4ocvXJqUuZ2Gl8Z7gzQzp+WFbLrn8vXj
LcyGGEETV84jy+X5cKu24eAjTFK+unfqwfxXFZP5vhIEVe7+uG6A/pMB5eLDqEUh
FQUcWqCF2Imt08Kcn7HL31GoIY0ABHdD+ICXZE5lTm6iJGzpFBKdTMm/e5igCJ3v
/tgtWZbnvyseLR/T/gU1JyheS9kNXP5sICwicBbY/vnGdEP6OKpDOSfQam5x4BBj
cvsBnsNuonY7OJn4iLY6LviQ0MM91PbaJUUJrp9Uyi4hj9iO/MZBaG0Giu0FKjG6
Vk+RlCYPjYIvHflQLZHe9BWLPN1AvaLKszt3IYaxS5seXCu0ZqHDGCBVqVCNDDJk
MJbHlrOVZ9T6mZhA+aQ1EJvTWk3MNj1AOyCJdiXtOOdg+4Fm5dN7nLpumLIg2yP2
afI7YfrPGA7sm+T0IMnOWxkK+KODC7OV9h/QjyBJDcUYGXLapuK9eP80cr8hKvH7
S3G4Top/rXDpnBNQ2azCqmUwaJWNRhLucC80Vd00d4pWIOwAPWpiV70Fq8OhQFhT
PNXwFXVLwtNfPvPxN1s+Vk+BBXp+M19AuQENBFqbaC8BCADSq89Z9xWRS2fvWI/N
+yEWliIU8XiqC9Ch+/6mS2LEyzB1pPLIIQcRvM6rq2dxXIRveVGpb63ck9vUtuJG
//es+DnDkO7re+ZmWHX+LAqMYNdaobSYxHkkR4CcY2HbPSEUbb//Zwk4BDyp3g3W
bKK9noVbslZuSwWNrxjX/Hieh/dIGYkNFeWOlmNfUYsevzqNDjsziOagyXKxLc++
hUM3GKgzXRQJBvBpgzQc4bRY+YGHXtZurk9AiZ4ZBhWv2Qrb5OYYislE9sdv3KWV
Iv1EBpbkAJ9MM1HgS8bkIOIpNs4XxHY6fTWWdrXi+NgZXQwQRYaWTQsXL3mktarS
fFfTABEBAAGJAiUEGAEIAA8FAlqbaC8CGwwFCQHhM4AACgkQcuM+TfGlA24vqg/8
CsVBHO4mh8SSaxdWNEU+mG4pU230BRCwrfn42wuSKb7WNLTTcWMDNI0KY/JNcWSq
G2qa6lngiAyOS72Jd635ptZ6Wvjd0WtBt90NN2jtn+aRqwQ8uItlYMQscofFzskj
QnBF+NWER+44nxboghuQ041m6aI2XmYUErSOBZi6onbC3svH6coMldkkiueWFbdB
qac3UXue4LUcaGR5T9pCQsLgTl3D8V5icEM+HpTVVGQZkVrOuKMKe6T9N5FS/WFu
T6CuFf/OyU15a6RE4WW9QqKYsaHl8B6+0P7uqPoVIxs8hfJcwaUu9XwIiZYBZg7N
yYCQ7JBapC5KZlIcTCfFSxby8lCJoZbIM3Pk/pgCuKxGaS9rHHUGuIvz8TfnM9FO
2zlxl4E6k3NFgGKF3p6oiKayC74o6EOw50p6DMjrisG7kkWVsTRCMINF7CcfeVme
MI9ljGAMB1hPtHPhl27hMRfq+/iIbR9gb7+Xw2yKQL2QRjMDIGGxP3q4NjD4tV8P
VyTbAAwNARG8oMpNM628v3tsW+WYNot1SPUQuZbIx1pCwMeTqljWsdQxWRVW5UxM
dnXTCqZhQwH0ICG/jbepbP6ciVB/CSa7TVohEK6jiTMorhqynRMMJ6p48Z6HIlyY
0Ss8q9K29eXaqmLB8Oy3HmupqxH95TqMntqivzf6i6e5AQ0EWptoPQEIAL1OdDIl
7E3VKAEWH5GnMzdnl9bju/ovoMjLqGevHS9Gyz4OPyZvCQ2pS8k0sgqwsn4F8vWM
7L3xKTyQTSYOPby3do58+kxUrdTNlqGKEEcZDG+MSzxKyft7m+37fzbg6tcU+O3L
/7m8nYWQSRKJeist7Q8HrQJzehuzcgAnNmpeBqXHnAwRBvtqORvz5cQAIQ4EsEvP
f/unTjw95JtL1LtBOaOaynF9ap/TZ34OvDdARmZSdqPpRtEvjfgIboIYYt1dNmDH
kiSaaKaqBLCJTD2z5KT8ccDeF8lzYHAYzNy8v2lTc9vagCZH+lf3d2d6umNcr4y1
NGEN4ZEhrmt/lP0AEQEAAYkDRAQYAQgADwUCWptoPQIbAgUJAeEzgAEpCRBy4z5N
8aUDbsBdIAQZAQgABgUCWptoPQAKCRD619WmVzqkJDTvB/49MQNQk8YJTwAnbdSH
7stU2uQFBbkljE8Juz5WJK53lL6xUVUp/3gKrQio1F+z9uRVqRh0cQnqX6mPMe5a
2dlHEIDHTJjSlR5GCCBRDbssV6SN72xSVgbxVGZ9L32qUYtiwGnxwXQC9D9KsonD
YfGfUhD1CLAldr6HwhJkOq4QKz5GF4ty8sMKEcpM5UaR2sa2y6Ebn9Vzma10YaVp
X7RlZM/iTiDhTmWuxLh7e21DI95k/eFqHpKA912N0n1BdzZPbwk83nVRxXg793NU
RFpegzlLawtaCW9oVJOYqErMGOYN5nbXAHXsr5X7Or70v1Yo1khgzNOfnirO57T9
VjT0J1QP/j1xobgMuNda7Fpwc0xo2oIKEf+SWY9GQrkUK7wCLDbpgbGVxTmREkyE
6oyDzW1QpQXRjLS9Wvtun0J3Wn6r6Aar0VaGKa7uiiq8UORWtFkWQAzzyBj87Rjx
eWZWV1dzLK7eMJdyN0gsOzcejrsOqf1sydzvhm4K66byjDZ78piv0DdyPIb4OsiQ
QU2GH+QwGRYIkYlU9f9g+hSasAfzvrATHlJZNrOjOCgXbut/yP9ug3DHKj76wmoU
n/Y4rpmskAzIQrZIpimkpNBmZVTGr4bkWcokVzrRFor3NCpl1qA1K9Cd43wARH8t
Zwk4evI4abbqUId0vVNCKSSDyCCjgNwRsmU8RXdn7r0vs4ObKuWfY9Yl2y8tq3qO
YPHr0r50YXWtKqUNy5JUc3Ow9DFR1p4O4yfmiSyTLUyOYbglfvtnO32OJkrrZ8Kq
iSDnyiq9u2nYJAEHk7AchF5TJrTCnd8yWNIjohild+wc+rMKktspoEcxmT6zaK4T
AymmEe3jzQhlxptpBm68t2E5kaYFQh+NnizXlRcmFjBgEhH2CxCoerUpK82Y+MuE
S/ODmF9kULre14aXAAspj4vldQ/LJm0SYEfTkE1sDipJQUzv6oS5AFloQDXZPWTB
15P+Xsj8sJV9hWCfJZVmppWuPg/pCYXwdjUHUYouTz3ZL6qnUbm2uQINBFpZUO0B
EADZkfsbXPpDcMALUgVmB3cJU90tFqc8Q5guK9oSs3ibx4SmyhBVmeF2TF6PQNoK
YvpUR50hAcx2AbwtY51u0XxrAr8kFiL6R5ce/0pVMfXGchcC58CJ3uf+O+OPt080
ftyVSTsY9xEnBohMoJescn0L/IPaM6KkkIFIMAI4Ct3QCHox7WHgPLrqB7Efx2Dj
Qkgjbioqj8zVKDwxTs0S3sknch675gOhsCkaI7KMcRGACDinKRF3wQha4brNa8En
vPTV01Cv0ttCo6NCcbQzQi8QQYpMQcWVkquEJWweZQvL/OvYWdT13JgnIp66pkmo
+JvGTOqQpSnIx6OQnV9yqwqsg4E0dkCE+9rDYAHpwvmRkaI2sItjN4KAEQdTWES8
RgGVgfCtvNH87PqpaPIgarMDY/j5KqTDp/7Nc5oGLCmhwZiYzQa7Bm5uVNnYIyOO
d1IjfclgVdVAzMOmrFytvXFCBcga1khL15taC7s6Vuld89TgMZdSot2RVz8W8Xc+
39ZrBvzrCeYsPq5/U0Z85cnOSw4skwh06wsxTvL1D70SilI2c0YdR1sVgbhq04HN
7FyE7SDQ1GqxyTJAU+OPH3Pk97Bl25vWD43RCCIjSUHhKzQRPno2ItObFepE+QJH
lSO1YMXmZDAfsRts3dca3VSDOdAQely6G7HQu5kXWXGtRQARAQABiQIfBBgBCAAJ
BQJaWVDtAhsMAAoJEHLjPk3xpQNuRlsQAKnkyjjXRvfMB3eKZ1PrWf7DBx5WL8Hk
r2QAnv0diDeRTzotQyzKivf3/W3gQc9kQi/ilaPuuXeW+yKiNQaIbai7EC0DdyHa
qG9s8F7UDoojFOGCc3OVpQvuucVbv4a6EpqXBI6ayrQW0jMXakiuIF/dL5uCGRLn
sPMB87xJfMrkqEziymJMooQTRckgj2S9J2QYDZFxmKChPl1kXMlmx6Y4FhzrsYwo
I47hW9hHG1+8129FOgwYTwELEuX6FKShcKpyy77b4Tar3UvdzNkfaysFPvX3O7Oh
Bes2VgfslEZSgK2CScigvLIz9Ehe9CUw6WEC6LZW3bbC+Cbz624gOsm/GYI9Llsc
5/NMMwQTCoTRm+b0UAYQvzHDS7km9yceNSfFlkpE/lWnIt9E0H+8bOwEbYF8y2qy
yLXIm7MYEm4UnUZ0j8kihP+wSHsZP2xPhjEUcQw1ZWhWLACvzlEC0a3zsovoJ6U8
zrqqfEBtuQgfwwJRWArMLQn/rlEJSrTrFfehwhvH3dPVSU36N5nBA8ls5YlSHBQv
38dChpBXu3wzFhetkSuHxdlfopeZMtDmljnIkBNTEFg01oqJNPbyiX2JQcfKizCt
maCIiJY+hOYIKkJdkt1FyOhADBciebxCQrpIIzWupeyQNuVj3I4g6YaQX00+kgiB
H1XKrAg/dpMNmQENBFrHiEoBCADASg9zHYzaSU0/1q1hcmTHU6H4syCQXHHd3zF7
n/RcsGnt4RBuUi/BUvNp3zYR6uFOyyk6LPV1hq2Ca8e/oSFrDYxqLladESQd9GNN
stDeK3HinsWJCVwSbkzNJbUtyr6SclmWt66vNqBZngMallJRQe8QDqpg0ZSZj/0d
VGxPBR16zc/2ddGnXJFe/V5XAWAap9SEo44pyGK4xf87Bgq8jT33LuQtd8exOk3E
atkK5jLEn9xmiheoSePEhOoQSrJMHfMjFka0PYZlCeaaHw7r7yXb/VoHFOAPxb6k
a1cunbp39b4z7Jy9kLBy0tbDnAs/sLp4LUN3Vx1JLoXBSIsHABEBAAG0JFJhdWwg
Sm9yZGFuIDxyYXVsQHByeXNtYXRpY2xhYnMuY29tPokBNwQTAQoAIQUCWseISgIb
AwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRCVRSpwGBD+26lmB/wJxChWwva0
StjMRSk3V7JTBPi5RNQm3VY8UydUNjsXzHVvtjUczOj+zHfo8tYUYa/ypWujXEX9
bVYVMr9JGNjm+rysI1gmW1gcx9pZr9gde4CR4Owfpwjh8oFnSrBBrcaelb0Krrv4
Okms43fEw1bWpllayal5SqknOIxpw1ZiNpG3jVe/C9n1/3Nw4XF5R0RHDxXTu6Hu
H3t7zRQwAJcOod6ccRdzNR9CsGdnOoNPG3pqs9w6zWUp0QETMAMcEpSLCJumaVfQ
24PK+MF92F5JRwNVt80xSLA9KMyNnv/ZvxZXXLjkIhsAmwYkHUs3WSm5HJ4qqOCX
V8VwFbwnea3eiQIzBBABCgAdFiEECuAFHWR7o8GpF69AcuM+TfGlA24FAl9zs2AA
CgkQcuM+TfGlA24dMA/+N31SPAXVgwiNasBknb+YSq2/OQPogxQUc8tupvDcQ62H
u0kvA7pUPUFjITJ1xsm8CRXfb7Hge9rNUw9Y2MNKf4sIDQs3bFeKOiAGVbO8Z055
5VCTWWPhXzjWoR84YWrx0Go8WT/V3Lahy4frGA3Vsza6wzi2P6c7LF4jqX2iBD1l
OpAYNGyt0sX/RLp3s2jOTWJwVyRR4UKSZOgpi9OTGLXrq5oU2dpwEIzBmhaWIs+u
oD5/4TaAt4lEFu3Sxk5w8fJlUXbM4IG8A1l+dnRPF5rtjtfvuX0GeQcDtJ5e1qHj
7PvVj8HjGPwxqsAjYHpg6QjyQCdtHYHdboEIU+OXMYRPRh2Iv0GUoeuMqoSsvFgn
c9PGN8Ai5u+oNzKeLJhpxpLV7s9zAbsripdnvDBn7RwuNx2ziqZayxoYvFRCAQl5
wzr0/eo/wq36D9EI7uJ2I3yt1g/VkwWQsAeE2skuGGbwed263cWTkl6g1w+vlDY3
/jc3a8HcS0zIUX194ChrbbNezGb74mQFoLk6PksLfhXseAKCs8bvPaTwIm0JGTMT
YzkRufrv1+I9KPFy3fTpvnMZTbud4nPCLsK179whk+Jrdv866i+E2WZ1JyzIZ9bB
P1x+ABi82PMdzhTw+pTkR1CVHmrmOiSi2MHRYGMedM9ECGnPIdab5d75r1qkuvO5
AQ0EWseISgEIAKHrgTVeZ0CWZMETk7NFjDTvBpoTMQDT7DDe2vFQHc8D2AvR3Aod
+CUaOeY0Yp0GOemd7BEcUbpYbCQk1B9G8vHNcQqTMLjBgujXwF6w2c+lqEu2/tyI
2/uGCOBDs4wuQZo+akCCMekqYjdZBfZV6nQzf/l7eQHIq+sNtnSiZmHdH46PLi7/
17wR9GxzKvuv1R73DCyekCcz1Puo0b7lfGD28kESJK1Mg9SAOqVjtaS58Oxo+Y1M
ZWRqh0tkAkgOBpdyddGy6TX/9c3a0U3eBQweRpNDh0eCEh5UsYDluL4NtXj7rVYd
4mHONJzI3h1LnKWvpVYmk703MPmtgeJwNzEAEQEAAYkBHwQYAQoACQUCWseISgIb
DAAKCRCVRSpwGBD+25PxCACNBj/2HBSpdYAxEGhNHSaw62y7Jwuf7NbsKIAqygzi
m2+dxae7PbAm64jEXYJA5GaCOs4xO52S/2+1N87e5J86VRNg0vlA9/ivFzERAxEg
rgIUyGXYfS8oA/4r5+PfKt/NvXO2wH3MPakrqZqXhOv+1IPvOt03wWoZKmYyVT6g
YnzutOsvH6cbhUh/D0WpuU8ZgkrFu5Xe7ynZoLm1qQOA23pkxxQbeNs0uoKUja9v
bx4eBtaliLc6rsXt+1WzdXA5ZRNqkdn87Tz5IU0FuQYVblYvPz9QoUlvx5siWVaP
Mmc7dIctWaWyaJmgjkLKdy36ydS5axhqn158yIjOZV3emQINBF8h6lMBEACovC4z
oieJ9iMZpWfylsLQKkeEmfSXnjcjW4RLUjs2CRWj+W6H7eCRy/MBOdx+6zAb8TE/
n/TSlP5l5Xx40BGDAMUZVFrJVEkMPK5kUmNzybg7PiuMd3qZE+pNyHEXXlLU77Dn
VO26TD9RvpKXdjm+ATsnQ6rvDNszkYI2Bj1tPxwZ7bRi96U/upL3WfYOsTLHirM3
pEkI3zfMZj8ufDX9XlmGrQ384E/hTgjpLXmDm/jMRlX3mRzDkV1HO+gEicfePm5+
K4eWlMCNXN5bcGwoEFY2LwAojRcbRaH/UH2S3btkG2eSK2fOFEwQ0G4vIyoLF60R
cEk1s6cYIgk3kVsmNSzA5iJ81nD5bbfTceUKsjTZiw5RmN0Vh5g75pw+3uoXB+55
egabEIt/GTZZlP6zhd/CKjTQR0R4+ZaEbZFOCtABukC5xfWGCRdNmXAWMBe0MYpW
ub2TRLISLfNNc7GWM4Y17d9aRhaql9gY6QLIRNGYuvGPiRMaJADZx46LtbWo8YiG
xLId7H8D+/0MSzMOg7RhELqYScYDigiVEXkTHA3QSprf/ohjm8woRhQY5CjCEZp5
8MvhD40VAo4Gxgx1V8lwB3CD3kDgFEaUZh2H+N/fmRegACN2lzEm1krOiS7sAB48
/Av99/1VXalLoBbzFTnuAYwnmLk8vdparT5LlwARAQABtChUZXJlbmNlIFRzYW8g
PHRlcmVuY2VAcHJ5c21hdGljbGFicy5jb20+iQJOBBMBCAA4FiEEMX1ukQWPjzwj
A7p3VjE+RFgSl6YFAl8h6lMCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ
VjE+RFgSl6YJgBAAqIAMzMFf/+qE896kuXYSlmaYtzhrMXgQVD09UgSq4JfVYudE
e8EfamWz8RFV7znxHO/5Fp4yoWeDGc2b40DhivvRb1p4XSJi+F64moeHt+qn4Hay
CDs5wGv40KJk0+2r7iILc3Gw4NP6r4c2HU2EqSW8fn/bYM3yxLsYEXt5zhgipKpR
CB4WmqojW+CxXkj8dv4CyY+HlKJ6nZWstK42h736njM44rjMDSDt3lv0ZYykopTw
09THnHkWOXY4PSrKOzE+OqsPMPOD3Gq3bYPqQ0ZgdS4FeuDesqqHjJabRX+7DgJK
lLEnylfDlvDKf6I/tqrAfqCCdQvEjpdQXG84GSdK//wT1biunHvGeyHM/PZx9V5O
X8YoecswcYjozU1F7x8buk8GxV7ZuJ2pbdXr7jTou1dA7e4Nas9Qu1RcK39MoTYc
Ub467ONFCX+Y3MzELTnEyx4hSwTxlWg7VjCQ63zrFOd8VG0WUydlqiHgIE8WCJVE
pQlrr2v/A6ieM1HY1Ftjt+mk/qncqibCdyIofyV4o5FrVo8arx74jR+Lhvkp1T9N
uRj8V6M3g9vxJdAsy1O5/ZrdwKJ6Yy1n62+9b/uxhklYONK7DpDlWU0ZLWHlKEIV
zzfILCiLf+nxMQdVwuthlcysg8JwYEE8xDXc851ciuj0ygv3Wm0BY44V6/m5Ag0E
XyHqUwEQALuKzOAlo75p2vSYD7TecE/E0hBOS+cjs8kRH+oIzm5fx7sf00SC1jU2
q5QLYLixNeT+l0bD70R7b8r2uFu1aZL7pQqbGIGisLHlxu8611+PCpE5AsQi3Wui
IZ6Y8K7grJ28vviBiZUBY3iCCRH0LuvyZN3R0zgyMGbzouQk5wuGJUkRHJKtV5by
FVEl3CYudRtAp5LPFw6j7UzT5yQqBmY6tXp5WMmmAvOtnu8ohpRhzY21dJMlSykX
Ne9rcARy8mVWNdcXJUIc85z0BmyrdiA4YY0XiZTHD9mslj+af4QHsaS+p3aorTLD
5BKkp5Ek79a1BUxBjrao4W2fljYf129/SHbwds/Dup26zB2vi/fhbfVPvevXLPpi
Vm4uz8fE4D5lPYZAdu5GtO2V9kWbhDtU1R1SJSdFDI9Sev3B+NLrstclGfdbFQKF
shbUxydjSX56OJvh5hee50PcCz+Ab+usoyUPkcOfET/L55AdqJo3cVYtnAKpOJG/
mKP5Ih3LZVm9wCdWTCzboEtDfLlcjCc5kLiE9Pq7sKMnXm/NcXNFWBkRuaHg+Mt5
Yk659/Q6oUG3yUrS2d7cSeuNRWNlaRlnk3hZtB13xpmoHGYmrMOe7wiEE5xEnOju
1ctRRRX6lNUPlSvID83Y9JSYL9hYMbidRmFY28AIddT/PjVTgfi1ABEBAAGJAjYE
GAEIACAWIQQxfW6RBY+PPCMDundWMT5EWBKXpgUCXyHqUwIbDAAKCRBWMT5EWBKX
poMOD/4/sRLnK94pY2qtSSfNZEumOdQVvges08u34saG4mT1iLD9TcRgsFvgwcTV
Pec9Git4iJmoJpFylvOzoBWmtDzJ7TB3JxvtwUfFH2uZ22k12eChyAFHI8TxASqI
TV2YwkIgB2PTmva1GrdNKM6y5bfS1BdS0u+Etgp4zN9nyQECY2sM2accUi2S7JBV
7o6lEJWCRgFUwIfY6fdfxhZo/w0g2u5wftUQYlbXWSQLImFFZBc/13k8EMxsfbMi
LQ/wxKEfe1ZwFoXqIS6cq8CHTdj70QO7K9ah6krGPmL23LVuxlkQIR7mT5yFJtv2
VRT4IYgOUl6rAd08B6MOy6MOMa14FpNrAybPK8Yd/eSdUNciVf17q33Yc15x+trs
En1hHbDS82xaLJ/Ld4mANeJVt3FodgVmzZGpKheFEOFXXeuX1ZZ4c9TgX+0wBKoh
aBb8EGBVo4aV4GbZ/gEa8wls5NNTwd56H4G94hiq+qFM39x4YjhAvkM0hLRYzR05
tSCdlEbkh2K6RbOhBPsNHCbypWRt2fN8/q4uLPJJt7NRQ2zi6H/x04HGblhXdX6H
mmYjJv1LTbem9VptcpvPauNsibeIvIWA2nYM2ncDWt6gJpOH9Zh4fHuaG4aCdNmJ
hPNeJNnmLcpDQvR9wU5w7e5tC/ZSeTZ5ul1zOKa1qZ4lJ50BDQ==
=a30p
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -3,24 +3,23 @@ Hash: SHA512
Contact: mailto:security@prysmaticlabs.com
Encryption: openpgp4fpr:0AE0051D647BA3C1A917AF4072E33E4DF1A5036E
Encryption: openpgp4fpr:341396BAFACC28C5082327F889725027FC8EC0D4
Encryption: openpgp4fpr:FEE44615A19049DF0CA0C2735E2B7E5734DFADCB
Encryption: openpgp4fpr:CD08DE68C60B82D3EE2A3F7D95452A701810FEDB
Encryption: openpgp4fpr:317D6E91058F8F3C2303BA7756313E44581297A6
Preferred-Languages: en
Canonical: https://github.com/prysmaticlabs/prysm/tree/master/.well-known/security.txt
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEECuAFHWR7o8GpF69AcuM+TfGlA24FAl6HrcwACgkQcuM+TfGl
A26voQ/8DFB5wUHP0uyY8k7FGbxhLzSeImxomnUHJaUGfdczbCdYPMEHc9zI1iZP
6LRiy9wS6qhqj/GSKVwvDPr+ZymXuV3L22GOP2lRhl7Z9Mm21ZJNOcoQBFOZnyHu
DAy9HeTmeuJxYkf8weqZYXyzEoKJBDmfuWmEFjrtMcFXUfT3aJn1E2A/AQdcVQIC
9L+iGWwFwjsPhcfaMuwcB7QMheDO6KSB7XPPCbrZ036Np8UTZ4qbZ5y73tlfkcOc
tYTrMSPtS4eNutiDOP5Np36cLzRtNpm/BziAK+7ZKiYY0HI5h9IkCTLO4x2UmAMX
sPoeaAB5z2QLIwmU9J2NhJrwiNMGTpJ+0bowy8U4cgzAX20CXVjRqGhy+cir8Ewg
DjEGjWINUw6W0yzJp0mKSKzuOhdTTmzIYBeMBsyce+pgN1KGFCxeIwxGxyJzADdw
mYQdljRXn4yEYP/KEpu/F2o8L4ptRO2jZWKvTvdzSSGGSyKyF4HsIRJ7m98DaB6S
0oGq1KpbKKTbQi5g8UShGV2gPeMCs5ZIIqK2b/cRzUet18aUuofLmR4lkKZa9yEG
rbzuJq/gB2vgQwExUEgVQ3/DfVc+y80e3YZ5s+rzV0vbLxl4Gh4yExpLo7hRf9iY
EFvMzH+BEEb5VfCwByZyV1BmesZVIosr7K6UmVtPe0bZGvv3uIg=
=5qpD
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
-----END PGP SIGNATURE-----

View File

@@ -14,6 +14,7 @@ exports_files([
# gazelle:prefix github.com/prysmaticlabs/prysm
# gazelle:map_kind go_library go_library @prysm//tools/go:def.bzl
# gazelle:map_kind go_test go_test @prysm//tools/go:def.bzl
# gazelle:map_kind go_repository go_repository @prysm//tools/go:def.bzl
gazelle(
name = "gazelle",
@@ -23,7 +24,16 @@ gazelle(
# Protobuf compiler (non-gRPC)
alias(
name = "proto_compiler",
actual = "@io_bazel_rules_go//proto:gogofast_proto",
actual = "@io_bazel_rules_go//proto:go_proto",
visibility = [
"//proto:__subpackages__",
],
)
# Cast protobuf compiler (non-gRPC)
alias(
name = "cast_proto_compiler",
actual = "@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast",
visibility = [
"//proto:__subpackages__",
],
@@ -32,21 +42,21 @@ alias(
# Protobuf compiler (gRPC)
alias(
name = "grpc_proto_compiler",
actual = "@io_bazel_rules_go//proto:gogofast_grpc",
actual = "@io_bazel_rules_go//proto:go_grpc",
visibility = ["//visibility:public"],
)
# Protobuf gRPC compiler without gogoproto. Required for gRPC gateway.
# Cast protobuf compiler (gRPC)
alias(
name = "grpc_nogogo_proto_compiler",
actual = "@io_bazel_rules_go//proto:go_grpc",
name = "cast_grpc_proto_compiler",
actual = "@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast_grpc",
visibility = ["//visibility:public"],
)
# Protobuf gRPC gateway compiler
alias(
name = "grpc_gateway_proto_compiler",
actual = "@com_github_grpc_ecosystem_grpc_gateway//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
actual = "@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
visibility = ["//visibility:public"],
)
@@ -111,6 +121,7 @@ nogo(
"//tools/analyzers/shadowpredecl:go_tool_library",
"//tools/analyzers/nop:go_tool_library",
"//tools/analyzers/slicedirect:go_tool_library",
"//tools/analyzers/interfacechecker:go_tool_library",
"//tools/analyzers/ineffassign:go_tool_library",
"//tools/analyzers/properpermissions:go_tool_library",
] + select({
@@ -147,3 +158,9 @@ string_setting(
"libfuzzer",
],
)
sh_binary(
name = "prysm_sh",
srcs = ["prysm.sh"],
visibility = ["//visibility:public"],
)

View File

@@ -4,7 +4,7 @@ Note: The latest and most up to date documenation can be found on our [docs port
Excited by our work and want to get involved in building out our sharding releases? Or maybe you haven't learned as much about the Ethereum protocol but are a savvy developer?
You can explore our [Open Issues](https://github.com/prysmaticlabs/prysm/issues) in-the works for our different releases. Feel free to fork our repo and start creating PRs after assigning yourself to an issue of interest. We are always chatting on [Discord](https://discord.gg/che9auJ) or [Gitter](https://gitter.im/prysmaticlabs/geth-sharding) drop us a line there if you want to get more involved or have any questions on our implementation!
You can explore our [Open Issues](https://github.com/prysmaticlabs/prysm/issues) in-the works for our different releases. Feel free to fork our repo and start creating PRs after assigning yourself to an issue of interest. We are always chatting on [Discord](https://discord.gg/CTYGPUJ) drop us a line there if you want to get more involved or have any questions on our implementation!
## Contribution Steps
@@ -62,12 +62,6 @@ Changes that only affect a single file can be tested with
$ go test <file_you_are_working_on>
```
Changes that affect multiple files can be tested with ...
```
$ golangci-lint run && bazel test //...
```
**10. Stage the file or files that you want to commit.**
```
@@ -181,7 +175,7 @@ We consider two types of contributions to our repo and categorize them as follow
### Part-Time Contributors
Anyone can become a part-time contributor and help out on implementing sharding. The responsibilities of a part-time contributor include:
Anyone can become a part-time contributor and help out on implementing Ethereum consensus. The responsibilities of a part-time contributor include:
- Engaging in Gitter conversations, asking the questions on how to begin contributing to the project
- Opening up github issues to express interest in code to implement
@@ -192,8 +186,6 @@ Anyone can become a part-time contributor and help out on implementing sharding.
- Follow up on open PRs
- Have an estimated timeframe to completion and let the core contributors know if a PR will take longer than expected
We do not expect all part-time contributors to be experts on all the latest sharding documentation, but all contributors should at least be familiarized with our sharding [README.md](https://github.com/prysmaticlabs/prysm/blob/master/validator/README.md) and have gone through the required Ethereum readings as posted on our [READINGS.md](https://github.com/prysmaticlabs/prysm/blob/master/docs/READINGS.md) document.
### Core Contributors
Core contributors are remote contractors of Prysmatic Labs, LLC. and are considered critical team members of our organization. Core devs have all of the responsibilities of part-time contributors plus the majority of the following:

View File

@@ -67,3 +67,14 @@ bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=deps.bzl%prysm_
The deps.bzl file should have been updated with the dependency and any transitive dependencies.
Do NOT add new `go_repository` to the WORKSPACE file. All dependencies should live in deps.bzl.
## Running tests
To enable conditional compilation and custom configuration for tests (where compiled code has more
debug info, while not being completely optimized), we rely on Go's build tags/constraints mechanism
(see official docs on [build constraints](https://golang.org/pkg/go/build/#hdr-Build_Constraints)).
Therefore, whenever using `go test`, do not forget to pass in extra build tag, eg:
```bash
go test ./beacon-chain/sync/initial-sync -tags develop
```

View File

@@ -1,6 +1,6 @@
# Prysm Client Interoperability Guide
This README details how to setup Prysm for interop testing for usage with other Ethereum 2.0 clients.
This README details how to setup Prysm for interop testing for usage with other Ethereum consensus clients.
## Installation & Setup

View File

@@ -1,20 +1,35 @@
# Prysm: An Ethereum 2.0 Client Written in Go
# Prysm: An Ethereum Consensus Implementation Written in Go
[![Build status](https://badge.buildkite.com/b555891daf3614bae4284dcf365b2340cefc0089839526f096.svg?branch=master)](https://buildkite.com/prysmatic-labs/prysm)
[![Go Report Card](https://goreportcard.com/badge/github.com/prysmaticlabs/prysm)](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
[![ETH2.0_Spec_Version 1.0.0](https://img.shields.io/badge/ETH2.0%20Spec%20Version-v1.0.0-blue.svg)](https://github.com/ethereum/eth2.0-specs/tree/v1.0.0)
[![Discord](https://user-images.githubusercontent.com/7288322/34471967-1df7808a-efbb-11e7-9088-ed0b04151291.png)](https://discord.gg/KSA7rPr)
[![Discord](https://user-images.githubusercontent.com/7288322/34471967-1df7808a-efbb-11e7-9088-ed0b04151291.png)](https://discord.gg/CTYGPUJ)
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the Ethereum 2.0 client specifications developed by [Prysmatic Labs](https://prysmaticlabs.com).
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/eth2/) specification, developed by [Prysmatic Labs](https://prysmaticlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
### Getting Started
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the [official documentation portal](https://docs.prylabs.network). If you still have questions, feel free to stop by our [Discord](https://discord.gg/KSA7rPr).
### Come join the testnet!
Participation is now open to the public for our Ethereum 2.0 phase 0 testnet release. Visit [prylabs.net](https://prylabs.net) for more information on the project or to sign up as a validator on the network. You can visualize the nodes in the network on [eth2stats.io](https://eth2stats.io), explore validator rewards/penalties via Bitfly's block explorer: [beaconcha.in](https://beaconcha.in), and follow the latest blocks added to the chain on [beaconscan](https://beaconscan.com).
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the [official documentation portal](https://docs.prylabs.network). If you still have questions, feel free to stop by our [Discord](https://discord.gg/CTYGPUJ).
### Staking on Mainnet
To participate in staking, you can join the [official eth2 launchpad](https://launchpad.ethereum.org). The launchpad is the only recommended way to become a validator on mainnet. You can explore validator rewards/penalties via Bitfly's block explorer: [beaconcha.in](https://beaconcha.in), and follow the latest blocks added to the chain on [beaconscan](https://beaconscan.com).
## Contributing
### Branches
Prysm maintains two permanent branches:
* [master](https://github.com/prysmaticlabs/prysm/tree/master): This points to the latest stable release. It is ideal for most users.
* [develop](https://github.com/prysmaticlabs/prysm/tree/develop): This is used for development, it contains the latest PRs. Developers should base their PRs on this branch.
### Guide
Want to get involved? Check out our [Contribution Guide](https://docs.prylabs.network/docs/contribute/contribution-guidelines/) to learn more!
## License
[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html)
## Legal Disclaimer
[Terms of Use](/TERMS_OF_SERVICE.md)

View File

@@ -5,7 +5,7 @@ Effective as of Oct 14, 2020
By downloading, accessing or using the Prysm implementation (“Prysm”), you (referenced herein as “you” or the “user”) certify that you have read and agreed to the terms and conditions below (the “Terms”) which form a binding contract between you and Prysmatic Labs (referenced herein as “we” or “us”). If you do not agree to the Terms, do not download or use Prysm.
### About Prysm
Prysm is a client implementation for Ethereum 2.0 Phase 0 protocol for a proof-of-stake blockchain. To participate in the network, a user must send ETH from the Eth1.0 chain into a validator deposit contract, which will queue in the user as a validator in the system. Validators participate in proposing and voting on blocks in the protocol, and the network applies rewards/penalties based on their behavior. A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the official documentation portal, however, we do not warrant the accuracy, completeness or usefulness of this documentation. Any reliance you place on such information is strictly at your own risk.
Prysm is a client implementation for Ethereum consensus protocol for a proof-of-stake blockchain. To participate in the network, a user must send ETH from the Eth1.0 chain into a validator deposit contract, which will queue in the user as a validator in the system. Validators participate in proposing and voting on blocks in the protocol, and the network applies rewards/penalties based on their behavior. A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the official documentation portal, however, we do not warrant the accuracy, completeness or usefulness of this documentation. Any reliance you place on such information is strictly at your own risk.
### Licensing Terms
Prysm is a fully open-source software program licensed pursuant to the GNU General Public License v3.0.
@@ -13,7 +13,7 @@ Prysm is a fully open-source software program licensed pursuant to the GNU Gener
The Prysmatic Labs name, the term “Prysm” and all related names, logos, product and service names, designs and slogans are trademarks of Prysmatic Labs or its affiliates and/or licensors. You must not use such marks without our prior written permission.
### Risks of Operating Prysm
The use of Prysm and acting as a validator on the Ethereum 2.0 network can lead to loss of money. Ethereum is still an experimental system and ETH remains a risky investment. You alone are responsible for your actions on Prysm including the security of your ETH and meeting any applicable minimum system requirements.
The use of Prysm and acting as a validator on the Ethereum network can lead to loss of money. Ethereum is still an experimental system and ETH remains a risky investment. You alone are responsible for your actions on Prysm including the security of your ETH and meeting any applicable minimum system requirements.
Use of Prysm and the ability to receive rewards or penalties may be affected at any time by mistakes made by the user or other users, software problems such as bugs, errors, incorrectly constructed transactions, unsafe cryptographic libraries or malware affecting the network, technical failures in the hardware of a user, security problems experienced by a user and/or actions or inactions of third parties and/or events experienced by third parties, among other risks. We cannot and do not guarantee that any user of Prysm will make money, that the Prysm network will operate in accordance with the documentation or that transactions will be effective or secure.

View File

@@ -1,43 +0,0 @@
# Testnet
The Prysmatic Labs test network is available for anyone to join. The easiest way to participate is by joining through the website, https://prylabs.net.
## Interop
For developers looking to connect a client other than Prysm to the test network, here is the relevant information for compatability.
**Spec version** - [v0.8.3](https://github.com/ethereum/eth2.0-specs/tree/v0.8.3)
**ETH 1 Deposit Contract Address** - See https://prylabs.net/contract. This contract is deployed on the [goerli](https://goerli.net/) network.
**Genesis time** - The ETH1 block time in which the 64th deposit to start ETH2 was included. This is NOT midnight of the next day as required by spec.
### ETH 2 Configuration
Use the [minimal config](https://github.com/ethereum/eth2.0-specs/blob/v0.8.3/configs/minimal.yaml) with the following changes.
| field | value |
|-------|-------|
| MIN_DEPOSIT_AMOUNT | 100 |
| MAX_EFFECTIVE_BALANCE | 3.2 * 1e9 |
| EJECTION_BALANCE | 1.6 * 1e9 |
| EFFECTIVE_BALANCE_INCREMENT | 0.1 * 1e9 |
| ETH1_FOLLOW_DISTANCE | 16 |
| GENESIS_FORK_VERSION | See [latest code](https://github.com/prysmaticlabs/prysm/blob/master/shared/params/config.go#L236) |
These parameters reduce the minimal config to 1/10 of the required ETH.
We have a genesis.ssz file available for download [here](https://prysmaticlabs.com/uploads/genesis.ssz)
### Connecting to the network
We have a libp2p bootstrap node available at `/dns4/prylabs.net/tcp/30001/p2p/16Uiu2HAm7Qwe19vz9WzD2Mxn7fXd1vgHHp4iccuyq7TxwRXoAGfc`.
Some of the Prysmatic Labs hosted nodes are behind a libp2p relay, so your libp2p implementation protocol should understand this functionality.
### Other
Undoubtably, you will have bugs. Reach out to us on [Discord](https://discord.gg/KSA7rPr) and be sure to capture issues on Github at https://github.com/prysmaticlabs/prysm/issues.
If you have instructions for you client, we would love to attempt this on your behalf. Kindly send over the instructions via github issue, PR, email to team@prysmaticlabs.com, or discord.

View File

@@ -1 +0,0 @@
0.2.0

190
WORKSPACE
View File

@@ -15,9 +15,9 @@ http_archive(
http_archive(
name = "com_grail_bazel_toolchain",
sha256 = "b924b102adc0c3368d38a19bd971cb4fa75362a27bc363d0084b90ca6877d3f0",
strip_prefix = "bazel-toolchain-0.5.7",
urls = ["https://github.com/grailbio/bazel-toolchain/archive/0.5.7.tar.gz"],
sha256 = "040b9d00b8a03e8a28e38159ad0f2d0e0de625d93f453a9f226971a8c47e757b",
strip_prefix = "bazel-toolchain-5f82830f9d6a1941c3eb29683c1864ccf2862454",
urls = ["https://github.com/grailbio/bazel-toolchain/archive/5f82830f9d6a1941c3eb29683c1864ccf2862454.tar.gz"],
)
load("@com_grail_bazel_toolchain//toolchain:deps.bzl", "bazel_toolchain_dependencies")
@@ -60,10 +60,10 @@ bazel_skylib_workspace()
http_archive(
name = "bazel_gazelle",
sha256 = "1f4fc1d91826ec436ae04833430626f4cc02c20bb0a813c0c2f3c4c421307b1d",
strip_prefix = "bazel-gazelle-e368a11b76e92932122d824970dc0ce5feb9c349",
sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f",
urls = [
"https://github.com/bazelbuild/bazel-gazelle/archive/e368a11b76e92932122d824970dc0ce5feb9c349.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
],
)
@@ -76,9 +76,9 @@ http_archive(
http_archive(
name = "io_bazel_rules_docker",
sha256 = "1698624e878b0607052ae6131aa216d45ebb63871ec497f26c67455b34119c80",
strip_prefix = "rules_docker-0.15.0",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.15.0/rules_docker-v0.15.0.tar.gz"],
sha256 = "59d5b42ac315e7eadffa944e86e90c2990110a1c8075f1cd145f487e999d22b3",
strip_prefix = "rules_docker-0.17.0",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.17.0/rules_docker-v0.17.0.tar.gz"],
)
http_archive(
@@ -88,11 +88,13 @@ http_archive(
# Required until https://github.com/bazelbuild/rules_go/pull/2450 merges otherwise nilness
# nogo check fails for certain third_party dependencies.
"//third_party:io_bazel_rules_go.patch",
# Expose internals of go_test for custom build transitions.
"//third_party:io_bazel_rules_go_test.patch",
],
sha256 = "207fad3e6689135c5d8713e5a17ba9d1290238f47b9ba545b63d9303406209c6",
sha256 = "7c10271940c6bce577d51a075ae77728964db285dac0a46614a7934dc34303e6",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.7/rules_go-v0.24.7.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.7/rules_go-v0.24.7.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.26.0/rules_go-v0.26.0.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.26.0/rules_go-v0.26.0.tar.gz",
],
)
@@ -100,14 +102,14 @@ http_archive(
# https://github.com/gogo/protobuf/pull/582 is merged.
git_repository(
name = "com_github_gogo_protobuf",
commit = "5628607bb4c51c3157aacc3a50f0ab707582b805",
commit = "b03c65ea87cdc3521ede29f62fe3ce239267c1bc",
patch_args = ["-p1"],
patches = [
"@io_bazel_rules_go//third_party:com_github_gogo_protobuf-gazelle.patch",
"//third_party:com_github_gogo_protobuf-equal.patch",
],
remote = "https://github.com/gogo/protobuf",
shallow_since = "1571033717 +0200",
shallow_since = "1610265707 +0000",
# gazelle args: -go_prefix github.com/gogo/protobuf -proto legacy
)
@@ -139,9 +141,9 @@ load(
container_pull(
name = "alpine_cc_linux_amd64",
digest = "sha256:3f7f4dfcb6dceac3a902f36609cc232262e49f5656a6dc4bb3da89e35fecc8a5",
digest = "sha256:752aa0c9a88461ffc50c5267bb7497ef03a303e38b2c8f7f2ded9bebe5f1f00e",
registry = "index.docker.io",
repository = "fasibio/alpine-libgcc",
repository = "pinglamb/alpine-glibc",
)
container_pull(
@@ -156,40 +158,10 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
go_register_toolchains(
go_version = "1.15.5",
go_version = "1.16.4",
nogo = "@//:nogo",
)
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies()
load("@io_bazel_rules_go//extras:embed_data_deps.bzl", "go_embed_data_dependencies")
go_embed_data_dependencies()
load("@com_github_atlassian_bazel_tools//gometalinter:deps.bzl", "gometalinter_dependencies")
gometalinter_dependencies()
load(
"@io_bazel_rules_docker//go:image.bzl",
_go_image_repos = "repositories",
)
# Golang images
# This is using gcr.io/distroless/base
_go_image_repos()
# CC images
# This is using gcr.io/distroless/base
load(
"@io_bazel_rules_docker//cc:image.bzl",
_cc_image_repos = "repositories",
)
_cc_image_repos()
http_archive(
name = "prysm_testnet_site",
build_file_content = """
@@ -210,20 +182,35 @@ http_archive(
url = "https://github.com/kubernetes/repo-infra/archive/6537f2101fb432b679f3d103ee729dd8ac5d30a0.tar.gz",
)
http_archive(
name = "eip3076_spec_tests",
build_file_content = """
filegroup(
name = "test_data",
srcs = glob([
"**/*.json",
]),
visibility = ["//visibility:public"],
)
""",
sha256 = "91434d5fd5e1c6eb7b0174fed2afe25e09bddf00e1e4c431db931b2cee4e7773",
url = "https://github.com/eth2-clients/slashing-protection-interchange-tests/archive/b8413ca42dc92308019d0d4db52c87e9e125c4e9.tar.gz",
)
http_archive(
name = "eth2_spec_tests_general",
build_file_content = """
filegroup(
name = "test_data",
srcs = glob([
"**/*.ssz",
"**/*.ssz_snappy",
"**/*.yaml",
]),
visibility = ["//visibility:public"],
)
""",
sha256 = "ef5396e4b13995da9776eeb5ae346a2de90970c28da3c4f0dcaa4ab9f0ad1f93",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/general.tar.gz",
sha256 = "deacc076365c727d653ac064894ecf0d1b0a675d86704dc8de271259f6a7314b",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/general.tar.gz",
)
http_archive(
@@ -232,14 +219,14 @@ http_archive(
filegroup(
name = "test_data",
srcs = glob([
"**/*.ssz",
"**/*.ssz_snappy",
"**/*.yaml",
]),
visibility = ["//visibility:public"],
)
""",
sha256 = "170551b441e7d54b73248372ad9ce8cb6c148810b5f1364637117a63f4f1c085",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/minimal.tar.gz",
sha256 = "6e9886af3d2f024e563249d70388129e28e3e92f742f289238ed9b7ec7a7f930",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/minimal.tar.gz",
)
http_archive(
@@ -248,38 +235,30 @@ http_archive(
filegroup(
name = "test_data",
srcs = glob([
"**/*.ssz",
"**/*.ssz_snappy",
"**/*.yaml",
]),
visibility = ["//visibility:public"],
)
""",
sha256 = "b541a9979b4703fa5ee5d2182b0b5313c38efc54ae7eaec2eef793230a52ec83",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/mainnet.tar.gz",
sha256 = "a7b3d0ffc02a567250f424d69b2474fdc9477cd56eada60af7474560b46a8527",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/mainnet.tar.gz",
)
http_archive(
name = "com_github_bazelbuild_buildtools",
sha256 = "b5d7dbc6832f11b6468328a376de05959a1a9e4e9f5622499d3bab509c26b46a",
strip_prefix = "buildtools-bf564b4925ab5876a3f64d8b90fab7f769013d42",
url = "https://github.com/bazelbuild/buildtools/archive/bf564b4925ab5876a3f64d8b90fab7f769013d42.zip",
sha256 = "7a182df18df1debabd9e36ae07c8edfa1378b8424a04561b674d933b965372b3",
strip_prefix = "buildtools-f2aed9ee205d62d45c55cfabbfd26342f8526862",
url = "https://github.com/bazelbuild/buildtools/archive/f2aed9ee205d62d45c55cfabbfd26342f8526862.zip",
)
load("@com_github_bazelbuild_buildtools//buildifier:deps.bzl", "buildifier_dependencies")
buildifier_dependencies()
git_repository(
name = "com_google_protobuf",
commit = "fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a", # v3.13.0
commit = "436bd7880e458532901c58f4d9d1ea23fa7edd52",
remote = "https://github.com/protocolbuffers/protobuf",
shallow_since = "1597443653 -0700",
shallow_since = "1617835118 -0700",
)
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
# Group the sources of the library so that CMake rule have access to it
all_content = """filegroup(name = "all", srcs = glob(["**"]), visibility = ["//visibility:public"])"""
@@ -316,33 +295,6 @@ http_archive(
# External dependencies
http_archive(
name = "sszgen", # Hack because we don't want to build this binary with libfuzzer, but need it to build.
build_file_content = """
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary")
go_library(
name = "go_default_library",
srcs = [
"sszgen/main.go",
"sszgen/marshal.go",
"sszgen/size.go",
"sszgen/unmarshal.go",
],
importpath = "github.com/ferranbt/fastssz/sszgen",
visibility = ["//visibility:private"],
)
go_binary(
name = "sszgen",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
""",
strip_prefix = "fastssz-06015a5d84f9e4eefe2c21377ca678fa8f1a1b09",
urls = ["https://github.com/ferranbt/fastssz/archive/06015a5d84f9e4eefe2c21377ca678fa8f1a1b09.tar.gz"],
)
http_archive(
name = "prysm_web_ui",
build_file_content = """
@@ -352,9 +304,9 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "6bb16ff0dc9348090cc31a9ea453643d32b617e66ac6e7bb38985d530070631b",
sha256 = "54ce527b83d092da01127f2e3816f4d5cfbab69354caba8537f1ea55889b6d7c",
urls = [
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/0.0.2-alpha/prysm-web-ui.tar.gz",
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/v1.0.0-beta.4/prysm-web-ui.tar.gz",
],
)
@@ -363,16 +315,50 @@ load("//:deps.bzl", "prysm_deps")
# gazelle:repository_macro deps.bzl%prysm_deps
prysm_deps()
load("@com_github_prysmaticlabs_go_ssz//:deps.bzl", "go_ssz_dependencies")
go_ssz_dependencies()
load("@prysm//third_party/herumi:herumi.bzl", "bls_dependencies")
bls_dependencies()
load(
"@io_bazel_rules_docker//go:image.bzl",
_go_image_repos = "repositories",
)
# Golang images
# This is using gcr.io/distroless/base
_go_image_repos()
# CC images
# This is using gcr.io/distroless/base
load(
"@io_bazel_rules_docker//cc:image.bzl",
_cc_image_repos = "repositories",
)
_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()
load("@com_github_atlassian_bazel_tools//gometalinter:deps.bzl", "gometalinter_dependencies")
gometalinter_dependencies()
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies()
load("@com_github_bazelbuild_buildtools//buildifier:deps.bzl", "buildifier_dependencies")
buildifier_dependencies()
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
# Do NOT add new go dependencies here! Refer to DEPENDENCIES.md!

View File

@@ -6,6 +6,6 @@
env -i \
PATH=/usr/bin:/bin \
HOME=$HOME \
GOOGLE_APPLICATION_CREDENTIALS=$GOOGLE_APPLICATION_CREDENTIALS \
HOME="$HOME" \
GOOGLE_APPLICATION_CREDENTIALS="$GOOGLE_APPLICATION_CREDENTIALS" \
bazel "$@"

View File

@@ -1,135 +1,19 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_test")
load("@io_bazel_rules_docker//go:image.bzl", "go_image")
load("@io_bazel_rules_docker//container:container.bzl", "container_bundle", "container_image")
load("//tools:go_image.bzl", "go_image_alpine", "go_image_debug")
load("@io_bazel_rules_docker//contrib:push-all.bzl", "docker_push")
load("//tools:target_migration.bzl", "moved_targets")
go_library(
name = "go_default_library",
srcs = [
"main.go",
"usage.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/flags:go_default_library",
"//beacon-chain/node:go_default_library",
"//shared/cmd:go_default_library",
"//shared/debug:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/journald:go_default_library",
"//shared/logutil:go_default_library",
"//shared/maxprocs:go_default_library",
"//shared/tos:go_default_library",
"//shared/version:go_default_library",
"@com_github_ethereum_go_ethereum//log:go_default_library",
"@com_github_ipfs_go_log_v2//:go_default_library",
"@com_github_joonix_log//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
"@com_github_x_cray_logrus_prefixed_formatter//:go_default_library",
],
)
go_image(
name = "image",
base = select({
"//tools:base_image_alpine": "//tools:alpine_cc_image",
"//tools:base_image_cc": "//tools:cc_image",
"//conditions:default": "//tools:cc_image",
}),
binary = ":beacon-chain",
tags = ["manual"],
visibility = ["//visibility:private"],
)
container_image(
name = "image_with_creation_time",
base = "image",
stamp = True,
)
container_bundle(
name = "image_bundle",
images = {
"gcr.io/prysmaticlabs/prysm/beacon-chain:latest": ":image_with_creation_time",
"gcr.io/prysmaticlabs/prysm/beacon-chain:{DOCKER_TAG}": ":image_with_creation_time",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:latest": ":image_with_creation_time",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:{DOCKER_TAG}": ":image_with_creation_time",
},
tags = ["manual"],
)
go_image_debug(
name = "image_debug",
image = ":image",
tags = ["manual"],
)
container_bundle(
name = "image_bundle_debug",
images = {
"gcr.io/prysmaticlabs/prysm/beacon-chain:latest-debug": ":image_debug",
"gcr.io/prysmaticlabs/prysm/beacon-chain:{DOCKER_TAG}-debug": ":image_debug",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:latest-debug": ":image_debug",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:{DOCKER_TAG}-debug": ":image_debug",
},
tags = ["manual"],
)
go_image_alpine(
name = "image_alpine",
image = ":image",
tags = ["manual"],
)
container_bundle(
name = "image_bundle_alpine",
images = {
"gcr.io/prysmaticlabs/prysm/beacon-chain:latest-alpine": ":image_alpine",
"gcr.io/prysmaticlabs/prysm/beacon-chain:{DOCKER_TAG}-alpine": ":image_alpine",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:latest-alpine": ":image_alpine",
"index.docker.io/prysmaticlabs/prysm-beacon-chain:{DOCKER_TAG}-alpine": ":image_alpine",
},
tags = ["manual"],
)
docker_push(
name = "push_images",
bundle = ":image_bundle",
tags = ["manual"],
)
docker_push(
name = "push_images_debug",
bundle = ":image_bundle_debug",
tags = ["manual"],
)
docker_push(
name = "push_images_alpine",
bundle = ":image_bundle_alpine",
tags = ["manual"],
)
go_binary(
name = "beacon-chain",
embed = [":go_default_library"],
visibility = [
"//beacon-chain:__subpackages__",
"//endtoend:__pkg__",
],
)
go_test(
name = "go_default_test",
size = "small",
srcs = ["usage_test.go"],
embed = [":go_default_library"],
deps = [
"//shared/featureconfig:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
moved_targets(
[
":push_images_debug",
":push_images_alpine",
":push_images",
":image_bundle_debug",
":image_debug",
":image_bundle_alpine",
":image_bundle",
":image_with_creation_time",
":image_alpine",
":image",
":go_default_test",
":beacon-chain",
],
"//cmd/beacon-chain",
)

View File

@@ -1,10 +1,9 @@
# Prysmatic Labs Beacon Chain Implementation
This is the main project folder for the beacon chain implementation of Ethereum Serenity in Golang by [Prysmatic Labs](https://prysmaticlabs.com). Before you begin, check out our [Contribution Guidelines](https://github.com/prysmaticlabs/prysm/blob/master/CONTRIBUTING.md) and join our active chat room on Discord or Gitter below:
This is the main project folder for the beacon chain implementation of Ethereum written in Go by [Prysmatic Labs](https://prysmaticlabs.com).
[![Discord](https://user-images.githubusercontent.com/7288322/34471967-1df7808a-efbb-11e7-9088-ed0b04151291.png)](https://discord.gg/KSA7rPr)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/prysmaticlabs/prysm?badge&utm_medium=badge&utm_campaign=pr-badge)
You can also read our main [README](https://github.com/prysmaticlabs/prysm/blob/master/README.md) and join our active chat room on Discord.
Also, read the latest beacon chain [design spec](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md), this design spec serves as a source of truth for the beacon chain implementation we follow at prysmatic labs.
Check out the [FAQs](https://notes.ethereum.org/9MMuzWeFTTSg-3Tz_YeiBA?view). Refer this page on [why](http://email.mg2.substack.com/c/eJwlj9GOhCAMRb9G3jRQQPGBh5mM8xsbhKrsDGIAM9m_X9xN2qZtbpt7rCm4xvSjj5gLOTOmL-809CMbKXFaOKakIl4DZYr2AGyQIGjHOnWH22OiYnoIxmDijaBhhS6fcy7GvjobA9m0mSXOcnZq5GBqLkilXBZhBsus5ZK89VbKkRt-a-BZI6DzZ7iur1lQ953KJ9bemnxgahuQU9XJu6pFPdu8meT8vragzEjpMCwMGLlgLo6h5z1JumQTu4IJd4v15xqMf_8ZLP_Y1bSLdbnrD-LL71i2Kj7DLxaWWF4)
we are combining sharding and casper together.
[![Discord](https://user-images.githubusercontent.com/7288322/34471967-1df7808a-efbb-11e7-9088-ed0b04151291.png)](https://discord.gg/CTYGPUJ)
Also, read the official beacon chain [specification](https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/beacon-chain.md), this design spec serves as a source of truth for the beacon chain implementation we follow at Prysmatic Labs.

View File

@@ -1,5 +1,4 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
@@ -27,7 +26,6 @@ go_library(
deps = [
"//beacon-chain/cache:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
@@ -35,7 +33,6 @@ go_library(
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/filters:go_default_library",
"//beacon-chain/flags:go_default_library",
"//beacon-chain/forkchoice:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
@@ -43,12 +40,17 @@ go_library(
"//beacon-chain/operations/voluntaryexits:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/interfaces:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/copyutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/mputil:go_default_library",
"//shared/params:go_default_library",
@@ -59,7 +61,7 @@ go_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",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
@@ -79,8 +81,10 @@ go_test(
srcs = [
"blockchain_test.go",
"chain_info_test.go",
"checktags_test.go",
"head_test.go",
"info_test.go",
"init_test.go",
"metrics_test.go",
"process_attestation_test.go",
"process_block_test.go",
@@ -90,6 +94,7 @@ go_test(
"weak_subjectivity_checks_test.go",
],
embed = [":go_default_library"],
gotags = ["develop"],
deps = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
@@ -101,8 +106,11 @@ go_test(
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//proto/beacon/db:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/eth/v1alpha1/wrapper:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
"//shared/params:go_default_library",
@@ -112,12 +120,10 @@ go_test(
"@com_github_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_x_net//context:go_default_library",
],
)
@@ -126,6 +132,8 @@ go_test(
name = "go_raceon_test",
srcs = [
"chain_info_norace_test.go",
"checktags_test.go",
"init_test.go",
"receive_block_test.go",
"service_norace_test.go",
],
@@ -137,6 +145,7 @@ go_test(
# See: https://github.com/etcd-io/bbolt/issues/187.
"-d=checkptr=0",
],
gotags = ["develop"],
race = "on",
tags = ["race_on"],
deps = [
@@ -150,6 +159,8 @@ go_test(
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/eth/v1alpha1/wrapper:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
"//shared/params:go_default_library",
@@ -159,11 +170,9 @@ go_test(
"@com_github_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_x_net//context:go_default_library",
],
)

View File

@@ -2,18 +2,14 @@ package blockchain
import (
"io/ioutil"
"os"
"testing"
"github.com/sirupsen/logrus"
)
func TestMain(m *testing.M) {
run := func() int {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(ioutil.Discard)
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(ioutil.Discard)
return m.Run()
}
os.Exit(run())
m.Run()
}

View File

@@ -4,15 +4,17 @@ import (
"context"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"go.opencensus.io/trace"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
// ChainInfoFetcher defines a common interface for methods in blockchain service which
@@ -22,15 +24,16 @@ type ChainInfoFetcher interface {
FinalizationFetcher
GenesisFetcher
CanonicalFetcher
ForkFetcher
}
// TimeFetcher retrieves the Eth2 data that's related to time.
// TimeFetcher retrieves the Ethereum consensus data that's related to time.
type TimeFetcher interface {
GenesisTime() time.Time
CurrentSlot() uint64
CurrentSlot() types.Slot
}
// GenesisFetcher retrieves the eth2 data related to its genesis.
// GenesisFetcher retrieves the Ethereum consensus data related to its genesis.
type GenesisFetcher interface {
GenesisValidatorRoot() [32]byte
}
@@ -38,15 +41,16 @@ type GenesisFetcher interface {
// HeadFetcher defines a common interface for methods in blockchain service which
// directly retrieves head related data.
type HeadFetcher interface {
HeadSlot() uint64
HeadSlot() types.Slot
HeadRoot(ctx context.Context) ([]byte, error)
HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error)
HeadState(ctx context.Context) (*state.BeaconState, error)
HeadValidatorsIndices(ctx context.Context, epoch uint64) ([]uint64, error)
HeadSeed(ctx context.Context, epoch uint64) ([32]byte, error)
HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
HeadState(ctx context.Context) (iface.BeaconState, error)
HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error)
HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error)
HeadGenesisValidatorRoot() [32]byte
HeadETH1Data() *ethpb.Eth1Data
ProtoArrayStore() *protoarray.Store
ChainHeads() ([][32]byte, []types.Slot)
}
// ForkFetcher retrieves the current fork information of the Ethereum beacon chain.
@@ -74,7 +78,7 @@ func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return state.CopyCheckpoint(s.finalizedCheckpt)
return copyutil.CopyCheckpoint(s.finalizedCheckpt)
}
// CurrentJustifiedCheckpt returns the current justified checkpoint from head state.
@@ -83,7 +87,7 @@ func (s *Service) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return state.CopyCheckpoint(s.justifiedCheckpt)
return copyutil.CopyCheckpoint(s.justifiedCheckpt)
}
// PreviousJustifiedCheckpt returns the previous justified checkpoint from head state.
@@ -92,11 +96,11 @@ func (s *Service) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return state.CopyCheckpoint(s.prevJustifiedCheckpt)
return copyutil.CopyCheckpoint(s.prevJustifiedCheckpt)
}
// HeadSlot returns the slot of the head of the chain.
func (s *Service) HeadSlot() uint64 {
func (s *Service) HeadSlot() types.Slot {
s.headLock.RLock()
defer s.headLock.RUnlock()
@@ -117,15 +121,15 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
return r[:], nil
}
b, err := s.beaconDB.HeadBlock(ctx)
b, err := s.cfg.BeaconDB.HeadBlock(ctx)
if err != nil {
return nil, err
}
if b == nil {
if b == nil || b.IsNil() {
return params.BeaconConfig().ZeroHash[:], nil
}
r, err := b.Block.HashTreeRoot()
r, err := b.Block().HashTreeRoot()
if err != nil {
return nil, err
}
@@ -136,7 +140,7 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
// HeadBlock returns the head block of the chain.
// If the head is nil from service struct,
// it will attempt to get the head block from DB.
func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
func (s *Service) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
@@ -144,13 +148,13 @@ func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, erro
return s.headBlock(), nil
}
return s.beaconDB.HeadBlock(ctx)
return s.cfg.BeaconDB.HeadBlock(ctx)
}
// HeadState returns the head state of the chain.
// If the head is nil from service struct,
// it will attempt to get the head state from DB.
func (s *Service) HeadState(ctx context.Context) (*state.BeaconState, error) {
func (s *Service) HeadState(ctx context.Context) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.HeadState")
defer span.End()
s.headLock.RLock()
@@ -163,22 +167,22 @@ func (s *Service) HeadState(ctx context.Context) (*state.BeaconState, error) {
return s.headState(ctx), nil
}
return s.stateGen.StateByRoot(ctx, s.headRoot())
return s.cfg.StateGen.StateByRoot(ctx, s.headRoot())
}
// HeadValidatorsIndices returns a list of active validator indices from the head view of a given epoch.
func (s *Service) HeadValidatorsIndices(ctx context.Context, epoch uint64) ([]uint64, error) {
func (s *Service) HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return []uint64{}, nil
return []types.ValidatorIndex{}, nil
}
return helpers.ActiveValidatorIndices(s.headState(ctx), epoch)
}
// HeadSeed returns the seed from the head view of a given epoch.
func (s *Service) HeadSeed(ctx context.Context, epoch uint64) ([32]byte, error) {
func (s *Service) HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
@@ -214,7 +218,7 @@ func (s *Service) HeadETH1Data() *ethpb.Eth1Data {
// ProtoArrayStore returns the proto array store object.
func (s *Service) ProtoArrayStore() *protoarray.Store {
return s.forkChoiceStore.Store()
return s.cfg.ForkChoiceStore.Store()
}
// GenesisTime returns the genesis time of beacon chain.
@@ -251,10 +255,32 @@ func (s *Service) CurrentFork() *pb.Fork {
// IsCanonical returns true if the input block root is part of the canonical chain.
func (s *Service) IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error) {
// If the block has been finalized, the block will always be part of the canonical chain.
if s.beaconDB.IsFinalizedBlock(ctx, blockRoot) {
if s.cfg.BeaconDB.IsFinalizedBlock(ctx, blockRoot) {
return true, nil
}
// If the block has not been finalized, check fork choice store to see if the block is canonical
return s.forkChoiceStore.IsCanonical(blockRoot), nil
return s.cfg.ForkChoiceStore.IsCanonical(blockRoot), nil
}
// ChainHeads returns all possible chain heads (leaves of fork choice tree).
// Heads roots and heads slots are returned.
func (s *Service) ChainHeads() ([][32]byte, []types.Slot) {
nodes := s.ProtoArrayStore().Nodes()
// Deliberate choice to not preallocate space for below.
// Heads cant be more than 2-3 in the worst case where pre-allocation will be 64 to begin with.
headsRoots := make([][32]byte, 0)
headsSlots := make([]types.Slot, 0)
nonExistentNode := ^uint64(0)
for _, node := range nodes {
// Possible heads have no children.
if node.BestDescendant() == nonExistentNode && node.BestChild() == nonExistentNode {
headsRoots = append(headsRoots, node.Root())
headsSlots = append(headsSlots, node.Slot())
}
}
return headsRoots, headsSlots
}

View File

@@ -4,16 +4,17 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestHeadSlot_DataRace(t *testing.T) {
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: db,
cfg: &Config{BeaconDB: beaconDB},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -22,11 +23,10 @@ func TestHeadSlot_DataRace(t *testing.T) {
}
func TestHeadRoot_DataRace(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: db,
head: &head{root: [32]byte{'A'}},
stateGen: stategen.New(db, sc),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{root: [32]byte{'A'}},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -36,11 +36,10 @@ func TestHeadRoot_DataRace(t *testing.T) {
}
func TestHeadBlock_DataRace(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: db,
head: &head{block: &ethpb.SignedBeaconBlock{}},
stateGen: stategen.New(db, sc),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{block: wrapper.WrappedPhase0SignedBeaconBlock(&ethpb.SignedBeaconBlock{})},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -50,10 +49,9 @@ func TestHeadBlock_DataRace(t *testing.T) {
}
func TestHeadState_DataRace(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: db,
stateGen: stategen.New(db, sc),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))

View File

@@ -5,18 +5,20 @@ import (
"testing"
"time"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"google.golang.org/protobuf/proto"
)
// Ensure Service implements chain info interface.
@@ -25,44 +27,44 @@ var _ TimeFetcher = (*Service)(nil)
var _ ForkFetcher = (*Service)(nil)
func TestFinalizedCheckpt_Nil(t *testing.T) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, beaconDB)
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], c.FinalizedCheckpt().Root, "Incorrect pre chain start value")
}
func TestHeadRoot_Nil(t *testing.T) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, beaconDB)
headRoot, err := c.HeadRoot(context.Background())
require.NoError(t, err)
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], headRoot, "Incorrect pre chain start value")
}
func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cp := &ethpb.Checkpoint{Epoch: 5, Root: bytesutil.PadTo([]byte("foo"), 32)}
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
c.finalizedCheckpt = cp
assert.Equal(t, cp.Epoch, c.FinalizedCheckpt().Epoch, "Unexpected finalized epoch")
}
func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
genesisRoot := [32]byte{'A'}
cp := &ethpb.Checkpoint{Root: genesisRoot[:]}
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
c.finalizedCheckpt = cp
c.genesisRoot = genesisRoot
assert.DeepEqual(t, c.genesisRoot[:], c.FinalizedCheckpt().Root)
}
func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
cp := &ethpb.Checkpoint{Epoch: 6, Root: bytesutil.PadTo([]byte("foo"), 32)}
c.justifiedCheckpt = cp
@@ -70,9 +72,9 @@ func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
}
func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
genesisRoot := [32]byte{'B'}
cp := &ethpb.Checkpoint{Root: genesisRoot[:]}
c.justifiedCheckpt = cp
@@ -81,21 +83,21 @@ func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
}
func TestPreviousJustifiedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cp := &ethpb.Checkpoint{Epoch: 7, Root: bytesutil.PadTo([]byte("foo"), 32)}
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
c.prevJustifiedCheckpt = cp
assert.Equal(t, cp.Epoch, c.PreviousJustifiedCheckpt().Epoch, "Unexpected previous justified epoch")
}
func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
genesisRoot := [32]byte{'C'}
cp := &ethpb.Checkpoint{Root: genesisRoot[:]}
c := setupBeaconChain(t, db, sc)
c := setupBeaconChain(t, beaconDB)
c.prevJustifiedCheckpt = cp
c.genesisRoot = genesisRoot
assert.DeepEqual(t, c.genesisRoot[:], c.PreviousJustifiedCheckpt().Root)
@@ -103,10 +105,10 @@ func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
func TestHeadSlot_CanRetrieve(t *testing.T) {
c := &Service{}
s, err := state.InitializeFromProto(&pb.BeaconState{})
s, err := v1.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c.head = &head{slot: 100, state: s}
assert.Equal(t, uint64(100), c.HeadSlot())
assert.Equal(t, types.Slot(100), c.HeadSlot())
}
func TestHeadRoot_CanRetrieve(t *testing.T) {
@@ -118,15 +120,15 @@ func TestHeadRoot_CanRetrieve(t *testing.T) {
}
func TestHeadRoot_UseDB(t *testing.T) {
db, _ := testDB.SetupDB(t)
c := &Service{beaconDB: db}
beaconDB := testDB.SetupDB(t)
c := &Service{cfg: &Config{BeaconDB: beaconDB}}
c.head = &head{root: params.BeaconConfig().ZeroHash}
b := testutil.NewBeaconBlock()
br, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveStateSummary(context.Background(), &pb.StateSummary{Root: br[:]}))
require.NoError(t, db.SaveHeadBlockRoot(context.Background(), br))
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
require.NoError(t, beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: br[:]}))
require.NoError(t, beaconDB.SaveHeadBlockRoot(context.Background(), br))
r, err := c.HeadRoot(context.Background())
require.NoError(t, err)
assert.Equal(t, br, bytesutil.ToBytes32(r))
@@ -135,18 +137,18 @@ func TestHeadRoot_UseDB(t *testing.T) {
func TestHeadBlock_CanRetrieve(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
s, err := state.InitializeFromProto(&pb.BeaconState{})
s, err := v1.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c := &Service{}
c.head = &head{block: b, state: s}
c.head = &head{block: wrapper.WrappedPhase0SignedBeaconBlock(b), state: s}
recevied, err := c.HeadBlock(context.Background())
require.NoError(t, err)
assert.DeepEqual(t, b, recevied, "Incorrect head block received")
assert.DeepEqual(t, b, recevied.Proto(), "Incorrect head block received")
}
func TestHeadState_CanRetrieve(t *testing.T) {
s, err := state.InitializeFromProto(&pb.BeaconState{Slot: 2, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
s, err := v1.InitializeFromProto(&pb.BeaconState{Slot: 2, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -163,7 +165,7 @@ func TestGenesisTime_CanRetrieve(t *testing.T) {
func TestCurrentFork_CanRetrieve(t *testing.T) {
f := &pb.Fork{Epoch: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Fork: f})
s, err := v1.InitializeFromProto(&pb.BeaconState{Fork: f})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -188,21 +190,21 @@ func TestGenesisValidatorRoot_CanRetrieve(t *testing.T) {
c := &Service{}
assert.Equal(t, [32]byte{}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
s, err := state.InitializeFromProto(&pb.BeaconState{GenesisValidatorsRoot: []byte{'a'}})
s, err := v1.InitializeFromProto(&pb.BeaconState{GenesisValidatorsRoot: []byte{'a'}})
require.NoError(t, err)
c.head = &head{state: s}
assert.Equal(t, [32]byte{'a'}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
}
func TestHeadETH1Data_Nil(t *testing.T) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, beaconDB)
assert.DeepEqual(t, &ethpb.Eth1Data{}, c.HeadETH1Data(), "Incorrect pre chain start value")
}
func TestHeadETH1Data_CanRetrieve(t *testing.T) {
d := &ethpb.Eth1Data{DepositCount: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Eth1Data: d})
s, err := v1.InitializeFromProto(&pb.BeaconState{Eth1Data: d})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -213,15 +215,15 @@ func TestHeadETH1Data_CanRetrieve(t *testing.T) {
func TestIsCanonical_Ok(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
c := setupBeaconChain(t, beaconDB)
blk := testutil.NewBeaconBlock()
blk.Block.Slot = 0
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, blk))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(blk)))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, root))
can, err := c.IsCanonical(ctx, root)
require.NoError(t, err)
assert.Equal(t, true, can)
@@ -277,7 +279,21 @@ func TestService_HeadGenesisValidatorRoot(t *testing.T) {
}
func TestService_ProtoArrayStore(t *testing.T) {
c := &Service{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{})}}
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))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 103, [32]byte{'d'}, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 104, [32]byte{'e'}, [32]byte{'b'}, [32]byte{}, 0, 0))
roots, slots := c.ChainHeads()
require.DeepEqual(t, [][32]byte{{'c'}, {'d'}, {'e'}}, roots)
require.DeepEqual(t, []types.Slot{102, 103, 104}, slots)
}

View File

@@ -0,0 +1,7 @@
// +build !develop
package blockchain
func init() {
log.Fatal("Tests in this package require extra build tag: re-run with `-tags develop`")
}

View File

@@ -6,24 +6,27 @@ import (
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// This defines the current chain service's view of head.
type head struct {
slot uint64 // current head slot.
root [32]byte // current head root.
block *ethpb.SignedBeaconBlock // current head block.
state *stateTrie.BeaconState // current head state.
slot types.Slot // current head slot.
root [32]byte // current head root.
block interfaces.SignedBeaconBlock // current head block.
state iface.BeaconState // current head state.
}
// Determined the head from the fork choice service and saves its new data
@@ -56,18 +59,18 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
// If the fork choice store is missing justified block info, a node should
// re-initiate fork choice store using the latest justified info.
// This recovers a fatal condition and should not happen in run time.
if !s.forkChoiceStore.HasNode(headStartRoot) {
jb, err := s.beaconDB.Block(ctx, headStartRoot)
if !s.cfg.ForkChoiceStore.HasNode(headStartRoot) {
jb, err := s.cfg.BeaconDB.Block(ctx, headStartRoot)
if err != nil {
return err
}
s.forkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block, headStartRoot, f, j); err != nil {
s.cfg.ForkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block(), headStartRoot, f, j); err != nil {
return err
}
}
headRoot, err := s.forkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
headRoot, err := s.cfg.ForkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
if err != nil {
return err
}
@@ -93,40 +96,50 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// If the head state is not available, just return nil.
// There's nothing to cache
if !s.stateGen.StateSummaryExists(ctx, headRoot) {
if !s.cfg.BeaconDB.HasStateSummary(ctx, headRoot) {
return nil
}
// Get the new head block from DB.
newHeadBlock, err := s.beaconDB.Block(ctx, headRoot)
newHeadBlock, err := s.cfg.BeaconDB.Block(ctx, headRoot)
if err != nil {
return err
}
if newHeadBlock == nil || newHeadBlock.Block == nil {
if newHeadBlock == nil || newHeadBlock.IsNil() || newHeadBlock.Block().IsNil() {
return errors.New("cannot save nil head block")
}
// Get the new head state from cached state or DB.
newHeadState, err := s.stateGen.StateByRoot(ctx, headRoot)
newHeadState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
if err != nil {
return errors.Wrap(err, "could not retrieve head state in DB")
}
if newHeadState == nil {
if newHeadState == nil || newHeadState.IsNil() {
return errors.New("cannot save nil head state")
}
// A chain re-org occurred, so we fire an event notifying the rest of the services.
headSlot := s.HeadSlot()
if bytesutil.ToBytes32(newHeadBlock.Block.ParentRoot) != bytesutil.ToBytes32(r) {
newHeadSlot := newHeadBlock.Block().Slot()
oldHeadRoot := s.headRoot()
oldStateRoot := s.headBlock().Block().StateRoot()
newStateRoot := newHeadBlock.Block().StateRoot()
if bytesutil.ToBytes32(newHeadBlock.Block().ParentRoot()) != bytesutil.ToBytes32(r) {
log.WithFields(logrus.Fields{
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block.Slot),
"newSlot": fmt.Sprintf("%d", newHeadSlot),
"oldSlot": fmt.Sprintf("%d", headSlot),
}).Debug("Chain reorg occurred")
s.stateNotifier.StateFeed().Send(&feed.Event{
absoluteSlotDifference := slotutil.AbsoluteValueSlotDifference(newHeadSlot, headSlot)
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Reorg,
Data: &statefeed.ReorgData{
NewSlot: newHeadBlock.Block.Slot,
OldSlot: headSlot,
Data: &ethpbv1.EventChainReorg{
Slot: newHeadSlot,
Depth: absoluteSlotDifference,
OldHeadBlock: oldHeadRoot[:],
NewHeadBlock: headRoot[:],
OldHeadState: oldStateRoot,
NewHeadState: newStateRoot,
Epoch: helpers.SlotToEpoch(newHeadSlot),
},
})
@@ -137,17 +150,28 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
s.setHead(headRoot, newHeadBlock, newHeadState)
// Save the new head root to DB.
if err := s.beaconDB.SaveHeadBlockRoot(ctx, headRoot); err != nil {
if err := s.cfg.BeaconDB.SaveHeadBlockRoot(ctx, headRoot); err != nil {
return errors.Wrap(err, "could not save head root in DB")
}
// Forward an event capturing a new chain head over a common event feed
// done in a goroutine to avoid blocking the critical runtime main routine.
go func() {
if err := s.notifyNewHeadEvent(newHeadSlot, newHeadState, newStateRoot, headRoot[:]); err != nil {
log.WithError(err).Error("Could not notify event feed of new chain head")
}
}()
return nil
}
// This gets called to update canonical root mapping. It does not save head block
// 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 *ethpb.SignedBeaconBlock, r [32]byte, hs *stateTrie.BeaconState) error {
func (s *Service) saveHeadNoDB(ctx context.Context, b interfaces.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
cachedHeadRoot, err := s.HeadRoot(ctx)
if err != nil {
return errors.Wrap(err, "could not get head root from cache")
@@ -156,24 +180,20 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
return nil
}
if b == nil || b.Block == nil {
return errors.New("cannot save nil head block")
}
s.setHeadInitialSync(r, stateTrie.CopySignedBeaconBlock(b), hs)
s.setHeadInitialSync(r, b.Copy(), hs)
return nil
}
// This sets head view object which is used to track the head slot, root, block and state.
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
func (s *Service) setHead(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
// This does a full copy of the block and state.
s.head = &head{
slot: block.Block.Slot,
slot: block.Block().Slot(),
root: root,
block: stateTrie.CopySignedBeaconBlock(block),
block: block.Copy(),
state: state.Copy(),
}
}
@@ -181,22 +201,22 @@ func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *
// This sets head view object which is used to track the head slot, root, block and state. The method
// assumes that state being passed into the method will not be modified by any other alternate
// caller which holds the state's reference.
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
func (s *Service) setHeadInitialSync(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
// This does a full copy of the block only.
s.head = &head{
slot: block.Block.Slot,
slot: block.Block().Slot(),
root: root,
block: stateTrie.CopySignedBeaconBlock(block),
block: block.Copy(),
state: state,
}
}
// This returns the head slot.
// This is a lock free version.
func (s *Service) headSlot() uint64 {
func (s *Service) headSlot() types.Slot {
return s.head.slot
}
@@ -214,14 +234,14 @@ func (s *Service) headRoot() [32]byte {
// This returns the head block.
// It does a full copy on head block for immutability.
// This is a lock free version.
func (s *Service) headBlock() *ethpb.SignedBeaconBlock {
return stateTrie.CopySignedBeaconBlock(s.head.block)
func (s *Service) headBlock() interfaces.SignedBeaconBlock {
return s.head.block.Copy()
}
// This returns the head state.
// It does a full copy on head state for immutability.
// This is a lock free version.
func (s *Service) headState(ctx context.Context) *stateTrie.BeaconState {
func (s *Service) headState(ctx context.Context) iface.BeaconState {
ctx, span := trace.StartSpan(ctx, "blockChain.headState")
defer span.End()
@@ -234,14 +254,6 @@ func (s *Service) headGenesisValidatorRoot() [32]byte {
return bytesutil.ToBytes32(s.head.state.GenesisValidatorRoot())
}
// HasHeadState returns true if head state exists.
func (s *Service) HasHeadState() bool {
s.headLock.RLock()
defer s.headLock.RUnlock()
return s.hasHeadState()
}
// Returns true if head state exists.
// This is the lock free version.
func (s *Service) hasHeadState() bool {
@@ -250,33 +262,33 @@ func (s *Service) hasHeadState() bool {
// This caches justified state balances to be used for fork choice.
func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot [32]byte) error {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
var justifiedState *stateTrie.BeaconState
var justifiedState iface.BeaconState
var err error
if justifiedRoot == s.genesisRoot {
justifiedState, err = s.beaconDB.GenesisState(ctx)
justifiedState, err = s.cfg.BeaconDB.GenesisState(ctx)
if err != nil {
return err
}
} else {
justifiedState, err = s.stateGen.StateByRoot(ctx, justifiedRoot)
justifiedState, err = s.cfg.StateGen.StateByRoot(ctx, justifiedRoot)
if err != nil {
return err
}
}
if justifiedState == nil {
if justifiedState == nil || justifiedState.IsNil() {
return errors.New("justified state can't be nil")
}
epoch := helpers.CurrentEpoch(justifiedState)
justifiedBalances := make([]uint64, justifiedState.NumValidators())
if err := justifiedState.ReadFromEveryValidator(func(idx int, val stateTrie.ReadOnlyValidator) error {
if err := justifiedState.ReadFromEveryValidator(func(idx int, val iface.ReadOnlyValidator) error {
if helpers.IsActiveValidatorUsingTrie(val, epoch) {
justifiedBalances[idx] = val.EffectiveBalance()
} else {
@@ -298,3 +310,53 @@ func (s *Service) getJustifiedBalances() []uint64 {
defer s.justifiedBalancesLock.RUnlock()
return s.justifiedBalances
}
// Notifies a common event feed of a new chain head event. Called right after a new
// chain head is determined, set, and saved to disk.
func (s *Service) notifyNewHeadEvent(
newHeadSlot types.Slot,
newHeadState iface.BeaconState,
newHeadStateRoot,
newHeadRoot []byte,
) error {
previousDutyDependentRoot := s.genesisRoot[:]
currentDutyDependentRoot := s.genesisRoot[:]
var previousDutyEpoch types.Epoch
currentDutyEpoch := helpers.SlotToEpoch(newHeadSlot)
if currentDutyEpoch > 0 {
previousDutyEpoch = currentDutyEpoch.Sub(1)
}
currentDutySlot, err := helpers.StartSlot(currentDutyEpoch)
if err != nil {
return errors.Wrap(err, "could not get duty slot")
}
previousDutySlot, err := helpers.StartSlot(previousDutyEpoch)
if err != nil {
return errors.Wrap(err, "could not get duty slot")
}
if currentDutySlot > 0 {
currentDutyDependentRoot, err = helpers.BlockRootAtSlot(newHeadState, currentDutySlot-1)
if err != nil {
return errors.Wrap(err, "could not get duty dependent root")
}
}
if previousDutySlot > 0 {
previousDutyDependentRoot, err = helpers.BlockRootAtSlot(newHeadState, previousDutySlot-1)
if err != nil {
return errors.Wrap(err, "could not get duty dependent root")
}
}
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.NewHead,
Data: &ethpbv1.EventHead{
Slot: newHeadSlot,
Block: newHeadRoot,
State: newHeadStateRoot,
EpochTransition: helpers.IsEpochEnd(newHeadSlot),
PreviousDutyDependentRoot: previousDutyDependentRoot,
CurrentDutyDependentRoot: currentDutyDependentRoot,
},
})
return nil
}

View File

@@ -5,9 +5,14 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -15,57 +20,78 @@ import (
)
func TestSaveHead_Same(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
r := [32]byte{'A'}
service.head = &head{slot: 0, root: r}
require.NoError(t, service.saveHead(context.Background(), r))
assert.Equal(t, uint64(0), service.headSlot(), "Head did not stay the same")
assert.Equal(t, types.Slot(0), service.headSlot(), "Head did not stay the same")
assert.Equal(t, r, service.headRoot(), "Head did not stay the same")
}
func TestSaveHead_Different(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
oldRoot := [32]byte{'A'}
service.head = &head{slot: 0, root: oldRoot}
service.head = &head{
slot: 0,
root: oldRoot,
block: wrapper.WrappedPhase0SignedBeaconBlock(
&ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 0,
StateRoot: make([]byte, 32),
},
},
),
}
newHeadSignedBlock := testutil.NewBeaconBlock()
newHeadSignedBlock.Block.Slot = 1
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(newHeadSignedBlock)))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
assert.Equal(t, types.Slot(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
require.NoError(t, err)
if !bytes.Equal(cachedRoot, newRoot[:]) {
t.Error("Head did not change")
}
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
assert.DeepEqual(t, cachedRoot, newRoot[:], "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
}
func TestSaveHead_Different_Reorg(t *testing.T) {
ctx := context.Background()
hook := logTest.NewGlobal()
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
oldRoot := [32]byte{'A'}
service.head = &head{slot: 0, root: oldRoot}
service.head = &head{
slot: 0,
root: oldRoot,
block: wrapper.WrappedPhase0SignedBeaconBlock(
&ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 0,
StateRoot: make([]byte, 32),
},
},
),
}
reorgChainParent := [32]byte{'B'}
newHeadSignedBlock := testutil.NewBeaconBlock()
@@ -73,45 +99,46 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
newHeadSignedBlock.Block.ParentRoot = reorgChainParent[:]
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(newHeadSignedBlock)))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
assert.Equal(t, types.Slot(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
require.NoError(t, err)
if !bytes.Equal(cachedRoot, newRoot[:]) {
t.Error("Head did not change")
}
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
require.LogsContain(t, hook, "Chain reorg occurred")
}
func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
state, _ := testutil.DeterministicGenesisState(t, 100)
r := [32]byte{'a'}
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), state, r))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), state, r))
require.NoError(t, service.cacheJustifiedStateBalances(context.Background(), r))
require.DeepEqual(t, service.getJustifiedBalances(), state.Balances(), "Incorrect justified balances")
}
func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
b := testutil.NewBeaconBlock()
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
@@ -121,3 +148,69 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
require.NoError(t, service.updateHead(context.Background(), []uint64{}))
}
func Test_notifyNewHeadEvent(t *testing.T) {
t.Run("genesis_state_root", func(t *testing.T) {
bState, _ := testutil.DeterministicGenesisState(t, 10)
notifier := &mock.MockStateNotifier{RecordEvents: true}
srv := &Service{
cfg: &Config{
StateNotifier: notifier,
},
genesisRoot: [32]byte{1},
}
newHeadStateRoot := [32]byte{2}
newHeadRoot := [32]byte{3}
err := srv.notifyNewHeadEvent(1, bState, newHeadStateRoot[:], newHeadRoot[:])
require.NoError(t, err)
events := notifier.ReceivedEvents()
require.Equal(t, 1, len(events))
eventHead, ok := events[0].Data.(*ethpbv1.EventHead)
require.Equal(t, true, ok)
wanted := &ethpbv1.EventHead{
Slot: 1,
Block: newHeadRoot[:],
State: newHeadStateRoot[:],
EpochTransition: false,
PreviousDutyDependentRoot: srv.genesisRoot[:],
CurrentDutyDependentRoot: srv.genesisRoot[:],
}
require.DeepSSZEqual(t, wanted, eventHead)
})
t.Run("non_genesis_values", func(t *testing.T) {
bState, _ := testutil.DeterministicGenesisState(t, 10)
notifier := &mock.MockStateNotifier{RecordEvents: true}
genesisRoot := [32]byte{1}
srv := &Service{
cfg: &Config{
StateNotifier: notifier,
},
genesisRoot: genesisRoot,
}
epoch1Start, err := helpers.StartSlot(1)
require.NoError(t, err)
epoch2Start, err := helpers.StartSlot(1)
require.NoError(t, err)
require.NoError(t, bState.SetSlot(epoch1Start))
newHeadStateRoot := [32]byte{2}
newHeadRoot := [32]byte{3}
err = srv.notifyNewHeadEvent(epoch2Start, bState, newHeadStateRoot[:], newHeadRoot[:])
require.NoError(t, err)
events := notifier.ReceivedEvents()
require.Equal(t, 1, len(events))
eventHead, ok := events[0].Data.(*ethpbv1.EventHead)
require.Equal(t, true, ok)
wanted := &ethpbv1.EventHead{
Slot: epoch2Start,
Block: newHeadRoot[:],
State: newHeadStateRoot[:],
EpochTransition: false,
PreviousDutyDependentRoot: genesisRoot[:],
CurrentDutyDependentRoot: make([]byte, 32),
}
require.DeepSSZEqual(t, wanted, eventHead)
})
}

View File

@@ -39,13 +39,13 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
log.WithError(err).Error("Could not get head state")
return
}
if headState == nil {
if headState == nil || headState.IsNil() {
if _, err := w.Write([]byte("Unavailable during initial syncing")); err != nil {
log.WithError(err).Error("Failed to render p2p info page")
}
}
nodes := s.forkChoiceStore.Nodes()
nodes := s.cfg.ForkChoiceStore.Nodes()
graph := dot.NewGraph(dot.Directed)
graph.Attr("rankdir", "RL")

View File

@@ -9,6 +9,7 @@ import (
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -20,23 +21,24 @@ func TestService_TreeHandler(t *testing.T) {
require.NoError(t, err)
ctx := context.Background()
db, sCache := testDB.SetupDB(t)
headState := testutil.NewBeaconState()
beaconDB := testDB.SetupDB(t)
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetBalances([]uint64{params.BeaconConfig().GweiPerEth}))
cfg := &Config{
BeaconDB: db,
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
[32]byte{'a'},
),
StateGen: stategen.New(db, sCache),
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.forkChoiceStore.ProcessBlock(ctx, 0, [32]byte{'a'}, [32]byte{'g'}, [32]byte{'c'}, 0, 0))
require.NoError(t, s.forkChoiceStore.ProcessBlock(ctx, 1, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'c'}, 0, 0))
s.setHead([32]byte{'a'}, testutil.NewBeaconBlock(), headState)
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(testutil.NewBeaconBlock()), headState)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(s.TreeHandler)

View File

@@ -1,11 +1,11 @@
package blockchain
import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
)
// This saves a beacon block to the initial sync blocks cache.
func (s *Service) saveInitSyncBlock(r [32]byte, b *ethpb.SignedBeaconBlock) {
func (s *Service) saveInitSyncBlock(r [32]byte, b interfaces.SignedBeaconBlock) {
s.initSyncBlocksLock.Lock()
defer s.initSyncBlocksLock.Unlock()
s.initSyncBlocks[r] = b
@@ -22,7 +22,7 @@ func (s *Service) hasInitSyncBlock(r [32]byte) bool {
// This retrieves a beacon block from the initial sync blocks cache using the root of
// the block.
func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
func (s *Service) getInitSyncBlock(r [32]byte) interfaces.SignedBeaconBlock {
s.initSyncBlocksLock.RLock()
defer s.initSyncBlocksLock.RUnlock()
b := s.initSyncBlocks[r]
@@ -31,11 +31,11 @@ func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
// This retrieves all the beacon blocks from the initial sync blocks cache, the returned
// blocks are unordered.
func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
func (s *Service) getInitSyncBlocks() []interfaces.SignedBeaconBlock {
s.initSyncBlocksLock.RLock()
defer s.initSyncBlocksLock.RUnlock()
blks := make([]*ethpb.SignedBeaconBlock, 0, len(s.initSyncBlocks))
blks := make([]interfaces.SignedBeaconBlock, 0, len(s.initSyncBlocks))
for _, b := range s.initSyncBlocks {
blks = append(blks, b)
}
@@ -46,5 +46,5 @@ func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
func (s *Service) clearInitSyncBlocks() {
s.initSyncBlocksLock.Lock()
defer s.initSyncBlocksLock.Unlock()
s.initSyncBlocks = make(map[[32]byte]*ethpb.SignedBeaconBlock)
s.initSyncBlocks = make(map[[32]byte]interfaces.SignedBeaconBlock)
}

View File

@@ -0,0 +1,12 @@
package blockchain
import (
"github.com/prysmaticlabs/prysm/shared/params"
)
func init() {
// Override network name so that hardcoded genesis files are not loaded.
cfg := params.BeaconConfig()
cfg.ConfigName = "test"
params.OverrideBeaconConfig(cfg)
}

View File

@@ -3,33 +3,56 @@ package blockchain
import (
"encoding/hex"
"fmt"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/sirupsen/logrus"
)
var log = logrus.WithField("prefix", "blockchain")
// logs state transition related data every slot.
func logStateTransitionData(b *ethpb.BeaconBlock) {
log.WithFields(logrus.Fields{
"attestations": len(b.Body.Attestations),
"deposits": len(b.Body.Deposits),
"attesterSlashings": len(b.Body.AttesterSlashings),
"proposerSlashings": len(b.Body.ProposerSlashings),
"voluntaryExits": len(b.Body.VoluntaryExits),
}).Info("Finished applying state transition")
func logStateTransitionData(b interfaces.BeaconBlock) {
log := log.WithField("slot", b.Slot)
if len(b.Body().Attestations()) > 0 {
log = log.WithField("attestations", len(b.Body().Attestations()))
}
if len(b.Body().Deposits()) > 0 {
log = log.WithField("deposits", len(b.Body().Deposits()))
}
if len(b.Body().AttesterSlashings()) > 0 {
log = log.WithField("attesterSlashings", len(b.Body().AttesterSlashings()))
}
if len(b.Body().ProposerSlashings()) > 0 {
log = log.WithField("proposerSlashings", len(b.Body().ProposerSlashings()))
}
if len(b.Body().VoluntaryExits()) > 0 {
log = log.WithField("voluntaryExits", len(b.Body().VoluntaryExits()))
}
log.Info("Finished applying state transition")
}
func logBlockSyncStatus(block *ethpb.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint) {
func logBlockSyncStatus(block interfaces.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
startTime, err := helpers.SlotToTime(genesisTime, block.Slot())
if err != nil {
return err
}
log.WithFields(logrus.Fields{
"slot": block.Slot,
"slotInEpoch": block.Slot % params.BeaconConfig().SlotsPerEpoch,
"slot": block.Slot(),
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"epoch": helpers.SlotToEpoch(block.Slot),
"epoch": helpers.SlotToEpoch(block.Slot()),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
}).Info("Synced new block")
log.WithFields(logrus.Fields{
"slot": block.Slot,
"sinceSlotStartTime": timeutils.Now().Sub(startTime),
"chainServiceProcessedTime": timeutils.Now().Sub(receivedTime),
}).Debug("Sync new block times")
return nil
}

View File

@@ -0,0 +1,66 @@
package blockchain
import (
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func Test_logStateTransitionData(t *testing.T) {
tests := []struct {
name string
b interfaces.BeaconBlock
want string
}{
{name: "empty block body",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}),
want: "\"Finished applying state transition\" prefix=blockchain slot=0",
},
{name: "has attestation",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{{}}}}),
want: "\"Finished applying state transition\" attestations=1 prefix=blockchain slot=0",
},
{name: "has deposit",
b: wrapper.WrappedPhase0BeaconBlock(
&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{{}},
Deposits: []*ethpb.Deposit{{}}}}),
want: "\"Finished applying state transition\" attestations=1 deposits=1 prefix=blockchain slot=0",
},
{name: "has attester slashing",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{
AttesterSlashings: []*ethpb.AttesterSlashing{{}}}}),
want: "\"Finished applying state transition\" attesterSlashings=1 prefix=blockchain slot=0",
},
{name: "has proposer slashing",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{
ProposerSlashings: []*ethpb.ProposerSlashing{{}}}}),
want: "\"Finished applying state transition\" prefix=blockchain proposerSlashings=1 slot=0",
},
{name: "has exit",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}}),
want: "\"Finished applying state transition\" prefix=blockchain slot=0 voluntaryExits=1",
},
{name: "has everything",
b: wrapper.WrappedPhase0BeaconBlock(&ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{{}},
Deposits: []*ethpb.Deposit{{}},
AttesterSlashings: []*ethpb.AttesterSlashing{{}},
ProposerSlashings: []*ethpb.ProposerSlashing{{}},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}}),
want: "\"Finished applying state transition\" attestations=1 attesterSlashings=1 deposits=1 prefix=blockchain proposerSlashings=1 slot=0 voluntaryExits=1",
},
}
for _, tt := range tests {
hook := logTest.NewGlobal()
t.Run(tt.name, func(t *testing.T) {
logStateTransitionData(tt.b)
require.LogsContain(t, hook, tt.want)
})
}
}

View File

@@ -5,9 +5,11 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -108,7 +110,7 @@ var (
)
// reportSlotMetrics reports slot related metrics.
func reportSlotMetrics(stateSlot, headSlot, clockSlot uint64, finalizedCheckpoint *ethpb.Checkpoint) {
func reportSlotMetrics(stateSlot, headSlot, clockSlot types.Slot, finalizedCheckpoint *ethpb.Checkpoint) {
clockTimeSlot.Set(float64(clockSlot))
beaconSlot.Set(float64(stateSlot))
beaconHeadSlot.Set(float64(headSlot))
@@ -119,8 +121,8 @@ func reportSlotMetrics(stateSlot, headSlot, clockSlot uint64, finalizedCheckpoin
}
// reportEpochMetrics reports epoch related metrics.
func reportEpochMetrics(ctx context.Context, postState, headState *stateTrie.BeaconState) error {
currentEpoch := postState.Slot() / params.BeaconConfig().SlotsPerEpoch
func reportEpochMetrics(ctx context.Context, postState, headState iface.BeaconState) error {
currentEpoch := types.Epoch(postState.Slot() / params.BeaconConfig().SlotsPerEpoch)
// Validator instances
pendingInstances := 0
@@ -139,7 +141,7 @@ func reportEpochMetrics(ctx context.Context, postState, headState *stateTrie.Bea
slashingEffectiveBalance := uint64(0)
for i, validator := range postState.Validators() {
bal, err := postState.BalanceAtIndex(uint64(i))
bal, err := postState.BalanceAtIndex(types.ValidatorIndex(i))
if err != nil {
log.Errorf("Could not load validator balance: %v", err)
continue
@@ -226,8 +228,8 @@ func reportEpochMetrics(ctx context.Context, postState, headState *stateTrie.Bea
return nil
}
func reportAttestationInclusion(blk *ethpb.BeaconBlock) {
for _, att := range blk.Body.Attestations {
attestationInclusionDelay.Observe(float64(blk.Slot - att.Data.Slot))
func reportAttestationInclusion(blk interfaces.BeaconBlock) {
for _, att := range blk.Body().Attestations() {
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
}
}

View File

@@ -5,22 +5,38 @@ import (
"testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestReportEpochMetrics_BadHeadState(t *testing.T) {
s := testutil.NewBeaconState()
h := testutil.NewBeaconState()
s, err := testutil.NewBeaconState()
require.NoError(t, err)
h, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, h.SetValidators(nil))
err := reportEpochMetrics(context.Background(), s, h)
err = reportEpochMetrics(context.Background(), s, h)
require.ErrorContains(t, "failed to initialize precompute: nil validators in state", err)
}
func TestReportEpochMetrics_BadAttestation(t *testing.T) {
s := testutil.NewBeaconState()
h := testutil.NewBeaconState()
require.NoError(t, h.SetCurrentEpochAttestations([]*pb.PendingAttestation{{InclusionDelay: 0}}))
err := reportEpochMetrics(context.Background(), s, h)
s, err := testutil.NewBeaconState()
require.NoError(t, err)
h, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, h.AppendCurrentEpochAttestations(&pb.PendingAttestation{InclusionDelay: 0}))
err = reportEpochMetrics(context.Background(), s, h)
require.ErrorContains(t, "attestation with inclusion delay of 0", err)
}
func TestReportEpochMetrics_SlashedValidatorOutOfBound(t *testing.T) {
h, _ := testutil.DeterministicGenesisState(t, 1)
v, err := h.ValidatorAtIndex(0)
require.NoError(t, err)
v.Slashed = true
require.NoError(t, h.UpdateValidatorAtIndex(0, v))
require.NoError(t, h.AppendCurrentEpochAttestations(&pb.PendingAttestation{InclusionDelay: 1, Data: testutil.HydrateAttestationData(&eth.AttestationData{})}))
err = reportEpochMetrics(context.Background(), h, h)
require.ErrorContains(t, "slot 0 out of bounds", err)
}

View File

@@ -2,25 +2,21 @@ package blockchain
import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"go.opencensus.io/trace"
)
// ErrTargetRootNotInDB returns when the target block root of an attestation cannot be found in the
// beacon database.
var ErrTargetRootNotInDB = errors.New("target root does not exist in db")
// onAttestation is called whenever an attestation is received, verifies the attestation is valid and saves
// it to the DB. As a stateless function, this does not hold nor delay attestation based on the spec descriptions.
// The delay is handled by the caller in `processAttestation`.
// The delay is handled by the caller in `processAttestations`.
//
// Spec pseudocode definition:
// def on_attestation(store: Store, attestation: Attestation) -> None:
@@ -40,73 +36,68 @@ var ErrTargetRootNotInDB = errors.New("target root does not exist in db")
//
// # Update latest messages for attesting indices
// update_latest_messages(store, indexed_attestation.attesting_indices, attestation)
// TODO(#6072): This code path is highly untested. Requires comprehensive tests and simpler refactoring.
func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]uint64, error) {
func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onAttestation")
defer span.End()
if a == nil {
return nil, errors.New("nil attestation")
if err := helpers.ValidateNilAttestation(a); err != nil {
return err
}
if a.Data == nil {
return nil, errors.New("nil attestation.Data field")
}
if a.Data.Target == nil {
return nil, errors.New("nil attestation.Data.Target field")
if err := helpers.ValidateSlotTargetEpoch(a.Data); err != nil {
return err
}
tgt := copyutil.CopyCheckpoint(a.Data.Target)
tgt := stateTrie.CopyCheckpoint(a.Data.Target)
if helpers.SlotToEpoch(a.Data.Slot) != a.Data.Target.Epoch {
return nil, fmt.Errorf("data slot is not in the same epoch as target %d != %d", helpers.SlotToEpoch(a.Data.Slot), a.Data.Target.Epoch)
}
// Verify beacon node has seen the target block before.
if !s.hasBlock(ctx, bytesutil.ToBytes32(tgt.Root)) {
return nil, ErrTargetRootNotInDB
}
// Note that target root check is ignored here because it was performed in sync's validation pipeline:
// validate_aggregate_proof.go and validate_beacon_attestation.go
// If missing target root were to fail in this method, it would have just failed in `getAttPreState`.
// Retrieve attestation's data beacon block pre state. Advance pre state to latest epoch if necessary and
// save it to the cache.
baseState, err := s.getAttPreState(ctx, tgt)
if err != nil {
return nil, err
return err
}
genesisTime := baseState.GenesisTime()
// Verify attestation target is from current epoch or previous epoch.
if err := s.verifyAttTargetEpoch(ctx, genesisTime, uint64(timeutils.Now().Unix()), tgt); err != nil {
return nil, err
return err
}
// Verify attestation beacon block is known and not from the future.
if err := s.verifyBeaconBlock(ctx, a.Data); err != nil {
return nil, errors.Wrap(err, "could not verify attestation beacon block")
return errors.Wrap(err, "could not verify attestation beacon block")
}
// Verify LMG GHOST and FFG votes are consistent with each other.
if err := s.verifyLMDFFGConsistent(ctx, a.Data.Target.Epoch, a.Data.Target.Root, a.Data.BeaconBlockRoot); err != nil {
return nil, errors.Wrap(err, "could not verify attestation beacon block")
}
// Note that LMG GHOST and FFG consistency check is ignored because it was performed in sync's validation pipeline:
// validate_aggregate_proof.go and validate_beacon_attestation.go
// Verify attestations can only affect the fork choice of subsequent slots.
if err := helpers.VerifySlotTime(genesisTime, a.Data.Slot+1, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
return err
}
// Use the target state to validate attestation and calculate the committees.
indexedAtt, err := s.verifyAttestation(ctx, baseState, a)
// Use the target state to verify attesting indices are valid.
committee, err := helpers.BeaconCommitteeFromState(baseState, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return nil, err
return err
}
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, a, committee)
if err != nil {
return err
}
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
if indexedAtt.AttestingIndices == nil {
return nil, errors.New("nil attesting indices")
}
// Note that signature verification is ignored here because it was performed in sync's validation pipeline:
// validate_aggregate_proof.go and validate_beacon_attestation.go
// We assume trusted attestation in this function has verified signature.
// Update forkchoice store with the new attestation for updating weight.
s.forkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
return indexedAtt.AttestingIndices, nil
return nil
}

View File

@@ -1,28 +1,27 @@
package blockchain
import (
"bytes"
"context"
"fmt"
"strconv"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/mputil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// getAttPreState retrieves the att pre state by either from the cache or the DB.
func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*stateTrie.BeaconState, error) {
func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (iface.BeaconState, error) {
// Use a multilock to allow scoped holding of a mutex by a checkpoint root + epoch
// allowing us to behave smarter in terms of how this function is used concurrently.
epochKey := strconv.FormatUint(c.Epoch, 10 /* base 10 */)
epochKey := strconv.FormatUint(uint64(c.Epoch), 10 /* base 10 */)
lock := mputil.NewMultilock(string(c.Root) + epochKey)
lock.Lock()
defer lock.Unlock()
@@ -30,11 +29,11 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
}
if cachedState != nil {
if cachedState != nil && !cachedState.IsNil() {
return cachedState, nil
}
baseState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
baseState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for epoch %d", c.Epoch)
}
@@ -44,10 +43,16 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
return nil, err
}
if epochStartSlot > baseState.Slot() {
baseState = baseState.Copy()
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
if featureconfig.Get().EnableNextSlotStateCache {
baseState, err = state.ProcessSlotsUsingNextSlotCache(ctx, baseState, c.Root, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
} else {
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
}
if err := s.checkpointStateCache.AddCheckpointState(c, baseState); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
@@ -57,7 +62,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
// To avoid sharing the same state across checkpoint state cache and hot state cache,
// we don't add the state to check point cache.
has, err := s.stateGen.HasStateInCache(ctx, bytesutil.ToBytes32(c.Root))
has, err := s.cfg.StateGen.HasStateInCache(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, err
}
@@ -72,9 +77,9 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
// verifyAttTargetEpoch validates attestation is from the current or previous epoch.
func (s *Service) verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime uint64, c *ethpb.Checkpoint) error {
currentSlot := (nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot
currentSlot := types.Slot((nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot)
currentEpoch := helpers.SlotToEpoch(currentSlot)
var prevEpoch uint64
var prevEpoch types.Epoch
// Prevents previous epoch under flow
if currentEpoch > 1 {
prevEpoch = currentEpoch - 1
@@ -88,50 +93,20 @@ func (s *Service) verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime u
// verifyBeaconBlock verifies beacon head block is known and not from the future.
func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.AttestationData) error {
r := bytesutil.ToBytes32(data.BeaconBlockRoot)
b, err := s.beaconDB.Block(ctx, r)
b, err := s.cfg.BeaconDB.Block(ctx, r)
if err != nil {
return err
}
// If the block does not exist in db, check again if block exists in initial sync block cache.
// This could happen as the node first syncs to head.
if b == nil && s.hasInitSyncBlock(r) {
if (b == nil || b.IsNil()) && s.hasInitSyncBlock(r) {
b = s.getInitSyncBlock(r)
}
if b == nil || b.Block == nil {
return fmt.Errorf("beacon block %#x does not exist", bytesutil.Trunc(data.BeaconBlockRoot))
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
if b.Block.Slot > data.Slot {
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block.Slot, data.Slot)
if b.Block().Slot() > data.Slot {
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block().Slot(), data.Slot)
}
return nil
}
// verifyLMDFFGConsistent verifies LMD GHOST and FFG votes are consistent with each other.
func (s *Service) verifyLMDFFGConsistent(ctx context.Context, ffgEpoch uint64, ffgRoot, lmdRoot []byte) error {
ffgSlot, err := helpers.StartSlot(ffgEpoch)
if err != nil {
return err
}
r, err := s.ancestor(ctx, lmdRoot, ffgSlot)
if err != nil {
return err
}
if !bytes.Equal(ffgRoot, r) {
return errors.New("FFG and LMD votes are not consistent")
}
return nil
}
// verifyAttestation validates input attestation is valid.
func (s *Service) verifyAttestation(ctx context.Context, baseState *stateTrie.BeaconState, a *ethpb.Attestation) (*ethpb.IndexedAttestation, error) {
committee, err := helpers.BeaconCommitteeFromState(baseState, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return nil, err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, a, committee)
if err := blocks.VerifyIndexedAttestation(ctx, baseState, indexedAtt); err != nil {
return nil, errors.Wrap(err, "could not verify indexed attestation")
}
return indexedAtt, nil
}

View File

@@ -4,66 +4,70 @@ import (
"context"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/shared/timeutils"
)
func TestStore_OnAttestation(t *testing.T) {
func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(db, sc),
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
_, err = blockTree1(db, []byte{'g'})
_, err = blockTree1(t, beaconDB, []byte{'g'})
require.NoError(t, err)
BlkWithOutState := testutil.NewBeaconBlock()
BlkWithOutState.Block.Slot = 0
require.NoError(t, db.SaveBlock(ctx, BlkWithOutState))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(BlkWithOutState)))
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
require.NoError(t, err)
BlkWithStateBadAtt := testutil.NewBeaconBlock()
BlkWithStateBadAtt.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, BlkWithStateBadAtt))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(BlkWithStateBadAtt)))
BlkWithStateBadAttRoot, err := BlkWithStateBadAtt.Block.HashTreeRoot()
require.NoError(t, err)
s := testutil.NewBeaconState()
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(100*params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot))
BlkWithValidState := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
require.NoError(t, db.SaveBlock(ctx, BlkWithValidState))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(BlkWithValidState)))
BlkWithValidStateRoot, err := BlkWithValidState.Block.HashTreeRoot()
require.NoError(t, err)
s = testutil.NewBeaconState()
s, err = testutil.NewBeaconState()
require.NoError(t, err)
err = s.SetFork(&pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
tests := []struct {
name string
@@ -72,34 +76,29 @@ func TestStore_OnAttestation(t *testing.T) {
}{
{
name: "attestation's data slot not aligned with target vote",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Slot: params.BeaconConfig().SlotsPerEpoch, Target: &ethpb.Checkpoint{Root: make([]byte, 32)}}},
wantedErr: "data slot is not in the same epoch as target 1 != 0",
},
{
name: "attestation's target root not in db",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)}}},
wantedErr: "target root does not exist in db",
a: testutil.HydrateAttestation(&ethpb.Attestation{Data: &ethpb.AttestationData{Slot: params.BeaconConfig().SlotsPerEpoch, Target: &ethpb.Checkpoint{Root: make([]byte, 32)}}}),
wantedErr: "slot 32 does not match target epoch 0",
},
{
name: "no pre state for attestations's target block",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: BlkWithOutStateRoot[:]}}},
a: testutil.HydrateAttestation(&ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: BlkWithOutStateRoot[:]}}}),
wantedErr: "could not get pre state for epoch 0",
},
{
name: "process attestation doesn't match current epoch",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Slot: 100 * params.BeaconConfig().SlotsPerEpoch, Target: &ethpb.Checkpoint{Epoch: 100,
Root: BlkWithStateBadAttRoot[:]}}},
a: testutil.HydrateAttestation(&ethpb.Attestation{Data: &ethpb.AttestationData{Slot: 100 * params.BeaconConfig().SlotsPerEpoch, Target: &ethpb.Checkpoint{Epoch: 100,
Root: BlkWithStateBadAttRoot[:]}}}),
wantedErr: "target epoch 100 does not match current epoch",
},
{
name: "process nil attestation",
a: nil,
wantedErr: "nil attestation",
wantedErr: "attestation can't be nil",
},
{
name: "process nil field (a.Data) in attestation",
a: &ethpb.Attestation{},
wantedErr: "nil attestation.Data field",
wantedErr: "attestation's data can't be nil",
},
{
name: "process nil field (a.Target) in attestation",
@@ -112,13 +111,13 @@ func TestStore_OnAttestation(t *testing.T) {
AggregationBits: make([]byte, 1),
Signature: make([]byte, 96),
},
wantedErr: "nil attestation.Data.Target field",
wantedErr: "attestation's target can't be nil",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := service.onAttestation(ctx, tt.a)
err := service.onAttestation(ctx, tt.a)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
@@ -128,18 +127,44 @@ func TestStore_OnAttestation(t *testing.T) {
}
}
func TestStore_SaveCheckpointState(t *testing.T) {
func TestStore_OnAttestation_Ok(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisState, pks := testutil.DeterministicGenesisState(t, 64)
require.NoError(t, genesisState.SetGenesisTime(uint64(timeutils.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
att, err := testutil.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].Data.Target.Root)
copied := genesisState.Copy()
copied, err = state.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.onAttestation(ctx, att[0]))
}
func TestStore_SaveCheckpointState(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s := testutil.NewBeaconState()
s, err := testutil.NewBeaconState()
require.NoError(t, err)
err = s.SetFinalizedCheckpoint(&ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)})
require.NoError(t, err)
val := &ethpb.Validator{
@@ -151,7 +176,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
err = s.SetBalances([]uint64{0})
require.NoError(t, err)
r := [32]byte{'g'}
require.NoError(t, service.beaconDB.SaveState(ctx, s, r))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, r))
service.justifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
@@ -160,16 +185,16 @@ func TestStore_SaveCheckpointState(t *testing.T) {
r = bytesutil.ToBytes32([]byte{'A'})
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}))
s1, err := service.getAttPreState(ctx, cp1)
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}))
s2, err := service.getAttPreState(ctx, cp2)
require.NoError(t, err)
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
@@ -192,8 +217,8 @@ func TestStore_SaveCheckpointState(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
cp3 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}))
s3, err := service.getAttPreState(ctx, cp3)
require.NoError(t, err)
assert.Equal(t, s.Slot(), s3.Slot(), "Unexpected state slot")
@@ -201,30 +226,30 @@ func TestStore_SaveCheckpointState(t *testing.T) {
func TestStore_UpdateCheckpointState(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
epoch := uint64(1)
epoch := types.Epoch(1)
baseState, _ := testutil.DeterministicGenesisState(t, 1)
checkpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("hi"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)))
returned, err := service.getAttPreState(ctx, checkpoint)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), checkpoint.Epoch*params.BeaconConfig().SlotsPerEpoch, "Incorrectly returned base state")
assert.Equal(t, params.BeaconConfig().SlotsPerEpoch.Mul(uint64(checkpoint.Epoch)), returned.Slot(), "Incorrectly returned base state")
cached, err := service.checkpointStateCache.StateByCheckpoint(checkpoint)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), cached.Slot(), "State should have been cached")
epoch = uint64(2)
epoch = 2
newCheckpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("bye"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)))
returned, err = service.getAttPreState(ctx, newCheckpoint)
require.NoError(t, err)
s, err := helpers.StartSlot(newCheckpoint.Epoch)
@@ -235,75 +260,69 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
cached, err = service.checkpointStateCache.StateByCheckpoint(newCheckpoint)
require.NoError(t, err)
if !proto.Equal(returned.InnerStateUnsafe(), cached.InnerStateUnsafe()) {
t.Error("Incorrectly cached base state")
}
require.DeepSSZEqual(t, returned.InnerStateUnsafe(), cached.InnerStateUnsafe())
}
func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)}))
}
func TestAttEpoch_MatchCurrentEpoch(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Epoch: 1}))
}
func TestAttEpoch_NotMatch(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := 2 * params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := 2 * uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
err = service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)})
assert.ErrorContains(t, "target epoch 0 does not match current epoch 2 or prev epoch 1", err)
}
func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
d := &ethpb.AttestationData{
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
assert.ErrorContains(t, "beacon block 0x000000000000 does not exist", service.verifyBeaconBlock(ctx, d))
d := testutil.HydrateAttestationData(&ethpb.AttestationData{})
assert.ErrorContains(t, "signed beacon block can't be nil", service.verifyBeaconBlock(ctx, d))
}
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
@@ -313,15 +332,15 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
func TestVerifyBeaconBlock_OK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
@@ -329,65 +348,17 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
assert.NoError(t, service.verifyBeaconBlock(ctx, d), "Did not receive the wanted error")
}
func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
wanted := "FFG and LMD votes are not consistent"
assert.ErrorContains(t, wanted, service.verifyLMDFFGConsistent(context.Background(), 1, []byte{'a'}, r33[:]))
}
func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
err = service.verifyLMDFFGConsistent(context.Background(), 1, r32[:], r33[:])
assert.NoError(t, err, "Could not verify LMD and FFG votes to be consistent")
}
func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -396,7 +367,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -406,15 +377,15 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
func TestVerifyFinalizedConsistency_OK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -423,7 +394,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -433,9 +404,9 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
@@ -452,10 +423,10 @@ func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, b32.Block.Slot, r32, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, b33.Block.Slot, r33, r32, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, b32.Block.Slot, r32, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, b33.Block.Slot, r33, r32, [32]byte{}, 0, 0))
_, err = service.forkChoiceStore.Head(ctx, 0, r32, []uint64{}, 0)
_, err = service.cfg.ForkChoiceStore.Head(ctx, 0, r32, []uint64{}, 0)
require.NoError(t, err)
err = service.VerifyFinalizedConsistency(context.Background(), r33[:])
require.NoError(t, err)

View File

@@ -3,12 +3,18 @@ package blockchain
import (
"context"
"fmt"
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -17,8 +23,14 @@ import (
"go.opencensus.io/trace"
)
// A custom slot deadline for processing state slots in our cache.
const slotDeadline = 5 * time.Second
// A custom deadline for deposit trie insertion.
const depositDeadline = 20 * time.Second
// This defines size of the upper bound for initial sync block cache.
var initialSyncBlockCacheSize = 2 * params.BeaconConfig().SlotsPerEpoch
var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
// onBlock is called when a gossip block is received. It runs regular state transition on the block.
// The block's signing root should be computed before calling this method to avoid redundant
@@ -41,7 +53,8 @@ var initialSyncBlockCacheSize = 2 * params.BeaconConfig().SlotsPerEpoch
// assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root
//
// # Check the block is valid and compute the post-state
// state = state_transition(pre_state, signed_block, True)
// state = pre_state.copy()
// state_transition(state, signed_block, True)
// # Add new block to the store
// store.blocks[hash_tree_root(block)] = block
// # Add new state for this block to the store
@@ -70,36 +83,43 @@ var initialSyncBlockCacheSize = 2 * params.BeaconConfig().SlotsPerEpoch
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
// store.justified_checkpoint = state.current_justified_checkpoint
func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
defer span.End()
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return errors.New("nil block")
}
b := signed.Block
b := signed.Block()
preState, err := s.getBlockPreState(ctx, b)
if err != nil {
return err
}
set, postState, err := state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, signed)
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
if err != nil {
return errors.Wrap(err, "could not execute state transition")
}
valid, err := set.Verify()
if err != nil {
return errors.Wrap(err, "could not batch verify signature")
}
if !valid {
return errors.New("signature in block failed to verify")
return err
}
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, false /* reg sync */); err != nil {
return err
}
// Updating next slot state cache can happen in the background. It shouldn't block rest of the process.
if featureconfig.Get().EnableNextSlotStateCache {
go func() {
// Use a custom deadline here, since this method runs asynchronously.
// We ignore the parent method's context and instead create a new one
// with a custom deadline, therefore using the background context instead.
slotCtx, cancel := context.WithTimeout(context.Background(), slotDeadline)
defer cancel()
if err := state.UpdateNextSlotCache(slotCtx, blockRoot[:], postState); err != nil {
log.WithError(err).Debug("could not update next slot state cache")
}
}()
}
// Update justified check point.
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustified(ctx, postState); err != nil {
@@ -107,42 +127,67 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
}
}
// Update finalized check point.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
newFinalized := postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch
if featureconfig.Get().UpdateHeadTimely {
if newFinalized {
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = postState.FinalizedCheckpoint()
}
s.clearInitSyncBlocks()
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
}
// Send notification of the processed block to the state feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: signed.Block().Slot(),
BlockRoot: blockRoot,
SignedBlock: signed,
Verified: true,
},
})
}
// Update finalized check point.
if newFinalized {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
fRoot := bytesutil.ToBytes32(postState.FinalizedCheckpoint().Root)
if err := s.forkChoiceStore.Prune(ctx, fRoot); err != nil {
if err := s.cfg.ForkChoiceStore.Prune(ctx, fRoot); err != nil {
return errors.Wrap(err, "could not prune proto array fork choice nodes")
}
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
// Update deposit cache.
finalizedState, err := s.stateGen.StateByRoot(ctx, fRoot)
if err != nil {
return errors.Wrap(err, "could not fetch finalized state")
}
// We update the cache up to the last deposit index in the finalized block's state.
// We can be confident that these deposits will be included in some block
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
s.depositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
if featureconfig.Get().EnablePruningDepositProofs {
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.depositCache.PruneProofs(ctx, eth1DepositIndex); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
if !featureconfig.Get().UpdateHeadTimely {
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
}
go func() {
// Send an event regarding the new finalized checkpoint over a common event feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.FinalizedCheckpoint,
Data: &ethpbv1.EventFinalizedCheckpoint{
Epoch: postState.FinalizedCheckpoint().Epoch,
Block: postState.FinalizedCheckpoint().Root,
State: signed.Block().StateRoot(),
},
})
// Use a custom deadline here, since this method runs asynchronously.
// We ignore the parent method's context and instead create a new one
// with a custom deadline, therefore using the background context instead.
depCtx, cancel := context.WithTimeout(context.Background(), depositDeadline)
defer cancel()
if err := s.insertFinalizedDeposits(depCtx, fRoot); err != nil {
log.WithError(err).Error("Could not insert finalized deposits.")
}
}()
}
defer reportAttestationInclusion(b)
@@ -150,76 +195,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
return s.handleEpochBoundary(ctx, postState)
}
// onBlockInitialSyncStateTransition is called when an initial sync block is received.
// It runs state transition on the block and without fork choice and post operation pool processes.
// The block's signing root should be computed before calling this method to avoid redundant
// computation in this method and methods it calls into.
func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockInitialSyncStateTransition")
defer span.End()
if signed == nil || signed.Block == nil {
return errors.New("nil block")
}
b := signed.Block
// Retrieve incoming block's pre state.
if err := s.verifyBlkPreState(ctx, b); err != nil {
return err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(signed.Block.ParentRoot))
if err != nil {
return err
}
if preState == nil {
return fmt.Errorf("nil pre state for slot %d", b.Slot)
}
// Exit early if the pre state slot is higher than incoming block's slot.
if preState.Slot() >= signed.Block.Slot {
return nil
}
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
if err != nil {
return errors.Wrap(err, "could not execute state transition")
}
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, true /* init sync */); err != nil {
return err
}
// Save the latest block as head in cache.
if err := s.saveHeadNoDB(ctx, signed, blockRoot, postState); err != nil {
return err
}
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
if uint64(len(s.getInitSyncBlocks())) > initialSyncBlockCacheSize {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
}
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, postState.CurrentJustifiedCheckpoint()); err != nil {
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
}
return s.handleEpochBoundary(ctx, postState)
}
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock,
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
defer span.End()
@@ -227,21 +203,21 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
if len(blks) == 0 || len(blockRoots) == 0 {
return nil, nil, errors.New("no blocks provided")
}
if blks[0] == nil || blks[0].Block == nil {
if blks[0] == nil || blks[0].IsNil() || blks[0].Block().IsNil() {
return nil, nil, errors.New("nil block")
}
b := blks[0].Block
b := blks[0].Block()
// Retrieve incoming block's pre state.
if err := s.verifyBlkPreState(ctx, b); err != nil {
return nil, nil, err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot()))
if err != nil {
return nil, nil, err
}
if preState == nil {
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot)
if preState == nil || preState.IsNil() {
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot())
}
jCheckpoints := make([]*ethpb.Checkpoint, len(blks))
@@ -252,7 +228,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
Messages: [][32]byte{},
}
var set *bls.SignatureSet
boundaries := make(map[[32]byte]*stateTrie.BeaconState)
boundaries := make(map[[32]byte]iface.BeaconState)
for i, b := range blks {
set, preState, err = state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, b)
if err != nil {
@@ -277,14 +253,14 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
return nil, nil, errors.New("batch block signature verification failed")
}
for r, st := range boundaries {
if err := s.stateGen.SaveState(ctx, r, st); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
return nil, nil, err
}
}
// Also saves the last post state which to be used as pre state for the next batch.
lastB := blks[len(blks)-1]
lastBR := blockRoots[len(blockRoots)-1]
if err := s.stateGen.SaveState(ctx, lastBR, preState); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, lastBR, preState); err != nil {
return nil, nil, err
}
if err := s.saveHeadNoDB(ctx, lastB, lastBR, preState); err != nil {
@@ -295,19 +271,24 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
// handles a block after the block's batch has been verified, where we can save blocks
// their state summaries and split them off to relative hot/cold storage.
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb.SignedBeaconBlock,
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interfaces.SignedBeaconBlock,
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
b := signed.Block
b := signed.Block()
s.saveInitSyncBlock(blockRoot, signed)
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, fCheckpoint, jCheckpoint); err != nil {
return err
}
s.stateGen.SaveStateSummary(ctx, signed, blockRoot)
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: signed.Block().Slot(),
Root: blockRoot[:],
}); err != nil {
return err
}
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
if uint64(len(s.getInitSyncBlocks())) > initialSyncBlockCacheSize {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
@@ -329,8 +310,21 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
}
// Epoch boundary bookkeeping such as logging epoch summaries.
func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.BeaconState) error {
if postState.Slot() >= s.nextEpochBoundarySlot {
func (s *Service) handleEpochBoundary(ctx context.Context, postState iface.BeaconState) error {
if postState.Slot()+1 == s.nextEpochBoundarySlot {
// Update caches for the next epoch at epoch boundary slot - 1.
if err := helpers.UpdateCommitteeCache(postState, helpers.NextEpoch(postState)); err != nil {
return err
}
copied := postState.Copy()
copied, err := state.ProcessSlots(ctx, copied, copied.Slot()+1)
if err != nil {
return err
}
if err := helpers.UpdateProposerIndicesInCache(copied); err != nil {
return err
}
} else if postState.Slot() >= s.nextEpochBoundarySlot {
if err := reportEpochMetrics(ctx, postState, s.head.state); err != nil {
return err
}
@@ -339,46 +333,52 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.
if err != nil {
return err
}
// Update committees cache at epoch boundary slot.
// Update caches at epoch boundary slot.
// The following updates have short cut to return nil cheaply if fulfilled during boundary slot - 1.
if err := helpers.UpdateCommitteeCache(postState, helpers.CurrentEpoch(postState)); err != nil {
return err
}
if err := helpers.UpdateProposerIndicesInCache(postState, helpers.CurrentEpoch(postState)); err != nil {
if err := helpers.UpdateProposerIndicesInCache(postState); err != nil {
return err
}
}
return nil
}
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
// to gain information on the most current chain.
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte,
state *stateTrie.BeaconState) error {
fCheckpoint := state.FinalizedCheckpoint()
jCheckpoint := state.CurrentJustifiedCheckpoint()
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock, root [32]byte,
st iface.BeaconState) error {
fCheckpoint := st.FinalizedCheckpoint()
jCheckpoint := st.CurrentJustifiedCheckpoint()
if err := s.insertBlockToForkChoiceStore(ctx, blk, root, fCheckpoint, jCheckpoint); err != nil {
return err
}
// Feed in block's attestations to fork choice store.
for _, a := range blk.Body.Attestations {
committee, err := helpers.BeaconCommitteeFromState(state, a.Data.Slot, a.Data.CommitteeIndex)
for _, a := range blk.Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(st, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return err
}
indices := attestationutil.AttestingIndices(a.AggregationBits, committee)
s.forkChoiceStore.ProcessAttestation(ctx, indices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
indices, err := attestationutil.AttestingIndices(a.AggregationBits, committee)
if err != nil {
return err
}
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
}
return nil
}
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock,
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock,
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
return err
}
// Feed in block to fork choice store.
if err := s.forkChoiceStore.ProcessBlock(ctx,
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
blk.Slot(), root, bytesutil.ToBytes32(blk.ParentRoot()), bytesutil.ToBytes32(blk.Body().Graffiti()),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
@@ -388,19 +388,19 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState, initSync bool) error {
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
defer span.End()
if initSync {
s.saveInitSyncBlock(r, b)
} else if err := s.beaconDB.SaveBlock(ctx, b); err != nil {
return errors.Wrapf(err, "could not save block from slot %d", b.Block.Slot)
} else if err := s.cfg.BeaconDB.SaveBlock(ctx, b); err != nil {
return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot())
}
if err := s.stateGen.SaveState(ctx, r, state); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
return errors.Wrap(err, "could not save state")
}
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block, r, state); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block.Slot)
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block(), r, st); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block().Slot())
}
return nil
}

View File

@@ -6,25 +6,28 @@ import (
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
)
// CurrentSlot returns the current slot based on time.
func (s *Service) CurrentSlot() uint64 {
func (s *Service) CurrentSlot() types.Slot {
return helpers.CurrentSlot(uint64(s.genesisTime.Unix()))
}
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
// to retrieve the state in DB. It verifies the pre state's validity and the incoming block
// is in the correct time window.
func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*stateTrie.BeaconState, error) {
func (s *Service) getBlockPreState(ctx context.Context, b interfaces.BeaconBlock) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
defer span.End()
@@ -33,16 +36,16 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*
return nil, err
}
preState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot()))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot())
}
if preState == nil {
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot)
if preState == nil || preState.IsNil() {
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot())
}
// Verify block slot time is not from the future.
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
}
@@ -55,28 +58,28 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*
}
// verifyBlkPreState validates input block has a valid pre-state.
func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) error {
func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
defer span.End()
parentRoot := bytesutil.ToBytes32(b.ParentRoot)
parentRoot := bytesutil.ToBytes32(b.ParentRoot())
// Loosen the check to HasBlock because state summary gets saved in batches
// during initial syncing. There's no risk given a state summary object is just a
// a subset of the block object.
if !s.stateGen.StateSummaryExists(ctx, parentRoot) && !s.beaconDB.HasBlock(ctx, parentRoot) {
if !s.cfg.BeaconDB.HasStateSummary(ctx, parentRoot) && !s.cfg.BeaconDB.HasBlock(ctx, parentRoot) {
return errors.New("could not reconstruct parent state")
}
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot)); err != nil {
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot())); err != nil {
return err
}
has, err := s.stateGen.HasState(ctx, parentRoot)
has, err := s.cfg.StateGen.HasState(ctx, parentRoot)
if err != nil {
return err
}
if !has {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return errors.Wrap(err, "could not save initial sync blocks")
}
s.clearInitSyncBlocks()
@@ -90,15 +93,15 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
ctx, span := trace.StartSpan(ctx, "blockChain.VerifyBlkDescendant")
defer span.End()
fRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.finalizedCheckpt.Root))
finalizedBlkSigned, err := s.beaconDB.Block(ctx, fRoot)
finalizedBlkSigned, err := s.cfg.BeaconDB.Block(ctx, fRoot)
if err != nil {
return err
}
if finalizedBlkSigned == nil || finalizedBlkSigned.Block == nil {
if finalizedBlkSigned == nil || finalizedBlkSigned.IsNil() || finalizedBlkSigned.Block().IsNil() {
return errors.New("nil finalized block")
}
finalizedBlk := finalizedBlkSigned.Block
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot)
finalizedBlk := finalizedBlkSigned.Block()
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot())
if err != nil {
return errors.Wrap(err, "could not get finalized block root")
}
@@ -108,7 +111,7 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
if !bytes.Equal(bFinalizedRoot, fRoot[:]) {
err := fmt.Errorf("block %#x is not a descendent of the current finalized block slot %d, %#x != %#x",
bytesutil.Trunc(root[:]), finalizedBlk.Slot, bytesutil.Trunc(bFinalizedRoot),
bytesutil.Trunc(root[:]), finalizedBlk.Slot(), bytesutil.Trunc(bFinalizedRoot),
bytesutil.Trunc(fRoot[:]))
traceutil.AnnotateError(span, err)
return err
@@ -118,13 +121,13 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
// verifyBlkFinalizedSlot validates input block is not less than or equal
// to current finalized slot.
func (s *Service) verifyBlkFinalizedSlot(b *ethpb.BeaconBlock) error {
func (s *Service) verifyBlkFinalizedSlot(b interfaces.BeaconBlock) error {
finalizedSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
return err
}
if finalizedSlot >= b.Slot {
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot, finalizedSlot)
if finalizedSlot >= b.Slot() {
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot(), finalizedSlot)
}
return nil
}
@@ -137,45 +140,45 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
if helpers.SlotsSinceEpochStarts(s.CurrentSlot()) < params.BeaconConfig().SafeSlotsToUpdateJustified {
return true, nil
}
var newJustifiedBlockSigned *ethpb.SignedBeaconBlock
var newJustifiedBlockSigned interfaces.SignedBeaconBlock
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(newJustifiedCheckpt.Root))
var err error
if s.hasInitSyncBlock(justifiedRoot) {
newJustifiedBlockSigned = s.getInitSyncBlock(justifiedRoot)
} else {
newJustifiedBlockSigned, err = s.beaconDB.Block(ctx, justifiedRoot)
newJustifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, justifiedRoot)
if err != nil {
return false, err
}
}
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.Block == nil {
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.IsNil() || newJustifiedBlockSigned.Block().IsNil() {
return false, errors.New("nil new justified block")
}
newJustifiedBlock := newJustifiedBlockSigned.Block
newJustifiedBlock := newJustifiedBlockSigned.Block()
jSlot, err := helpers.StartSlot(s.justifiedCheckpt.Epoch)
if err != nil {
return false, err
}
if newJustifiedBlock.Slot <= jSlot {
if newJustifiedBlock.Slot() <= jSlot {
return false, nil
}
var justifiedBlockSigned *ethpb.SignedBeaconBlock
var justifiedBlockSigned interfaces.SignedBeaconBlock
cachedJustifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))
if s.hasInitSyncBlock(cachedJustifiedRoot) {
justifiedBlockSigned = s.getInitSyncBlock(cachedJustifiedRoot)
} else {
justifiedBlockSigned, err = s.beaconDB.Block(ctx, cachedJustifiedRoot)
justifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, cachedJustifiedRoot)
if err != nil {
return false, err
}
}
if justifiedBlockSigned == nil || justifiedBlockSigned.Block == nil {
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)
justifiedBlock := justifiedBlockSigned.Block()
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot())
if err != nil {
return false, err
}
@@ -185,7 +188,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
return true, nil
}
func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconState) error {
func (s *Service) updateJustified(ctx context.Context, state iface.ReadOnlyBeaconState) error {
cpt := state.CurrentJustifiedCheckpoint()
if cpt.Epoch > s.bestJustifiedCheckpt.Epoch {
s.bestJustifiedCheckpt = cpt
@@ -203,7 +206,7 @@ func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconSt
}
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cpt)
return s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cpt)
}
// This caches input checkpoint as justified for the service struct. It rotates current justified to previous justified,
@@ -216,26 +219,27 @@ func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpo
return err
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cp)
return s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cp)
}
func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) error {
// Blocks need to be saved so that we can retrieve finalized block from
// DB when migrating states.
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
if err := s.cfg.BeaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
return err
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
if !featureconfig.Get().UpdateHeadTimely {
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
}
fRoot := bytesutil.ToBytes32(cp.Root)
if err := s.stateGen.MigrateToCold(ctx, fRoot); err != nil {
if err := s.cfg.StateGen.MigrateToCold(ctx, fRoot); err != nil {
return errors.Wrap(err, "could not migrate to cold")
}
@@ -254,7 +258,7 @@ func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) err
// else:
// # root is older than queried slot, thus a skip slot. Return most recent root prior to slot
// return root
func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byte, error) {
func (s *Service) ancestor(ctx context.Context, root []byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestor")
defer span.End()
@@ -275,18 +279,18 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
}
// This retrieves an ancestor root using fork choice store. The look up is looping through the a flat array structure.
func (s *Service) ancestorByForkChoiceStore(ctx context.Context, r [32]byte, slot uint64) ([]byte, error) {
func (s *Service) ancestorByForkChoiceStore(ctx context.Context, r [32]byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByForkChoiceStore")
defer span.End()
if !s.forkChoiceStore.HasParent(r) {
if !s.cfg.ForkChoiceStore.HasParent(r) {
return nil, errors.New("could not find root in fork choice store")
}
return s.forkChoiceStore.AncestorRoot(ctx, r, slot)
return s.cfg.ForkChoiceStore.AncestorRoot(ctx, r, slot)
}
// This retrieves an ancestor root using DB. The look up is recursively looking up DB. Slower than `ancestorByForkChoiceStore`.
func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]byte, error) {
func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByDB")
defer span.End()
@@ -295,7 +299,7 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]
return nil, ctx.Err()
}
signed, err := s.beaconDB.Block(ctx, r)
signed, err := s.cfg.BeaconDB.Block(ctx, r)
if err != nil {
return nil, errors.Wrap(err, "could not get ancestor block")
}
@@ -304,15 +308,15 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]
signed = s.getInitSyncBlock(r)
}
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return nil, errors.New("nil block")
}
b := signed.Block
if b.Slot == slot || b.Slot < slot {
b := signed.Block()
if b.Slot() == slot || b.Slot() < slot {
return r[:], nil
}
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot), slot)
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot()), slot)
}
// This updates justified check point in store, if the new justified is later than stored justified or
@@ -330,7 +334,7 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
// store.justified_checkpoint = state.current_justified_checkpoint
func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *stateTrie.BeaconState) error {
func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state iface.BeaconState) error {
// Update justified if it's different than the one cached in the store.
if !attestationutil.CheckPointIsEqual(s.justifiedCheckpt, state.CurrentJustifiedCheckpoint()) {
if state.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
@@ -360,13 +364,13 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *state
// This retrieves missing blocks from DB (ie. the blocks that couldn't be received over sync) and inserts them to fork choice store.
// This is useful for block tree visualizer and additional vote accounting.
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.BeaconBlock,
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk interfaces.BeaconBlock,
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
pendingNodes := make([]*ethpb.BeaconBlock, 0)
pendingNodes := make([]interfaces.BeaconBlock, 0)
pendingRoots := make([][32]byte, 0)
parentRoot := bytesutil.ToBytes32(blk.ParentRoot)
slot := blk.Slot
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
slot := blk.Slot()
// Fork choice only matters from last finalized slot.
fSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
@@ -374,17 +378,17 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
}
higherThanFinalized := slot > fSlot
// As long as parent node is not in fork choice store, and parent node is in DB.
for !s.forkChoiceStore.HasNode(parentRoot) && s.beaconDB.HasBlock(ctx, parentRoot) && higherThanFinalized {
b, err := s.beaconDB.Block(ctx, parentRoot)
for !s.cfg.ForkChoiceStore.HasNode(parentRoot) && s.cfg.BeaconDB.HasBlock(ctx, parentRoot) && higherThanFinalized {
b, err := s.cfg.BeaconDB.Block(ctx, parentRoot)
if err != nil {
return err
}
pendingNodes = append(pendingNodes, b.Block)
pendingNodes = append(pendingNodes, b.Block())
copiedRoot := parentRoot
pendingRoots = append(pendingRoots, copiedRoot)
parentRoot = bytesutil.ToBytes32(b.Block.ParentRoot)
slot = b.Block.Slot
parentRoot = bytesutil.ToBytes32(b.Block().ParentRoot())
slot = b.Block().Slot()
higherThanFinalized = slot > fSlot
}
@@ -393,8 +397,8 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
for i := len(pendingNodes) - 1; i >= 0; i-- {
b := pendingNodes[i]
r := pendingRoots[i]
if err := s.forkChoiceStore.ProcessBlock(ctx,
b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti),
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
b.Slot(), r, bytesutil.ToBytes32(b.ParentRoot()), bytesutil.ToBytes32(b.Body().Graffiti()),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
@@ -404,15 +408,37 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
return nil
}
// inserts finalized deposits into our finalized deposit trie.
func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.insertFinalizedDeposits")
defer span.End()
// Update deposit cache.
finalizedState, err := s.cfg.StateGen.StateByRoot(ctx, fRoot)
if err != nil {
return errors.Wrap(err, "could not fetch finalized state")
}
// We update the cache up to the last deposit index in the finalized block's state.
// We can be confident that these deposits will be included in some block
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.cfg.DepositCache.PruneProofs(ctx, eth1DepositIndex); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
}
return nil
}
// The deletes input attestations from the attestation pool, so proposers don't include them in a block for the future.
func (s *Service) deletePoolAtts(atts []*ethpb.Attestation) error {
for _, att := range atts {
if helpers.IsAggregated(att) {
if err := s.attPool.DeleteAggregatedAttestation(att); err != nil {
if err := s.cfg.AttPool.DeleteAggregatedAttestation(att); err != nil {
return err
}
} else {
if err := s.attPool.DeleteUnaggregatedAttestation(att); err != nil {
if err := s.cfg.AttPool.DeleteUnaggregatedAttestation(att); err != nil {
return err
}
}

View File

@@ -3,20 +3,27 @@ package blockchain
import (
"context"
"fmt"
"math/big"
"strconv"
"testing"
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
types "github.com/prysmaticlabs/eth2-types"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -28,40 +35,41 @@ import (
func TestStore_OnBlock(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st := testutil.NewBeaconState()
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(db, validGenesisRoot[:])
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
random := testutil.NewBeaconBlock()
random.Block.Slot = 1
random.Block.ParentRoot = validGenesisRoot[:]
assert.NoError(t, db.SaveBlock(ctx, random))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(random)))
randomParentRoot, err := random.Block.HashTreeRoot()
assert.NoError(t, err)
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), randomParentRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), randomParentRoot))
randomParentRoot2 := roots[1]
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2}))
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), bytesutil.ToBytes32(randomParentRoot2)))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), bytesutil.ToBytes32(randomParentRoot2)))
tests := []struct {
name string
blk *ethpb.SignedBeaconBlock
s *stateTrie.BeaconState
s iface.BeaconState
time uint64
wantErrString string
}{
@@ -76,7 +84,7 @@ func TestStore_OnBlock(t *testing.T) {
blk: func() *ethpb.SignedBeaconBlock {
b := testutil.NewBeaconBlock()
b.Block.ParentRoot = randomParentRoot2
b.Block.Slot = params.BeaconConfig().FarFutureEpoch
b.Block.Slot = params.BeaconConfig().FarFutureSlot
return b
}(),
s: st.Copy(),
@@ -115,7 +123,7 @@ func TestStore_OnBlock(t *testing.T) {
root, err := tt.blk.Block.HashTreeRoot()
assert.NoError(t, err)
err = service.onBlock(ctx, tt.blk, root)
err = service.onBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(tt.blk), root)
assert.ErrorContains(t, tt.wantErrString, err)
})
}
@@ -123,62 +131,64 @@ func TestStore_OnBlock(t *testing.T) {
func TestStore_OnBlockBatch(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, wrapper.WrappedPhase0SignedBeaconBlock(genesis))
st, keys := testutil.DeterministicGenesisState(t, 64)
bState := st.Copy()
var blks []*ethpb.SignedBeaconBlock
var blks []interfaces.SignedBeaconBlock
var blkRoots [][32]byte
var firstState *stateTrie.BeaconState
var firstState iface.BeaconState
for i := 1; i < 10; i++ {
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), uint64(i))
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), types.Slot(i))
require.NoError(t, err)
bState, err = state.ExecuteStateTransition(ctx, bState, b)
bState, err = state.ExecuteStateTransition(ctx, bState, wrapper.WrappedPhase0SignedBeaconBlock(b))
require.NoError(t, err)
if i == 1 {
firstState = bState.Copy()
}
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
service.saveInitSyncBlock(root, b)
blks = append(blks, b)
service.saveInitSyncBlock(root, wrapper.WrappedPhase0SignedBeaconBlock(b))
blks = append(blks, wrapper.WrappedPhase0SignedBeaconBlock(b))
blkRoots = append(blkRoots, root)
}
blks[0].Block.ParentRoot = gRoot[:]
require.NoError(t, db.SaveBlock(context.Background(), blks[0]))
require.NoError(t, service.stateGen.SaveState(ctx, blkRoots[0], firstState))
rBlock, err := blks[0].PbPhase0Block()
assert.NoError(t, err)
rBlock.Block.ParentRoot = gRoot[:]
require.NoError(t, beaconDB.SaveBlock(context.Background(), blks[0]))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, blkRoots[0], firstState))
_, _, err = service.onBlockBatch(ctx, blks[1:], blkRoots[1:])
require.NoError(t, err)
}
func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
params.UseMinimalConfig()
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.genesisTime = time.Now()
@@ -195,10 +205,10 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.beaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(newJustifiedBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(lastJustifiedBlk)))
diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}
update, err = service.shouldUpdateCurrentJustified(ctx, &ethpb.Checkpoint{Root: newJustifiedRoot[:]})
@@ -208,11 +218,11 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
params.UseMinimalConfig()
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
lastJustifiedBlk := testutil.NewBeaconBlock()
@@ -223,10 +233,10 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.beaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(newJustifiedBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(lastJustifiedBlk)))
diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}
@@ -237,93 +247,95 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
s, err := v1.InitializeFromProto(&pb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, wrapper.WrappedPhase0SignedBeaconBlock(genesis))
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
b.Block.ParentRoot = gRoot[:]
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, wrapper.WrappedPhase0BeaconBlock(b.Block)))
}
func TestCachedPreState_CanGetFromDB(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, wrapper.WrappedPhase0SignedBeaconBlock(genesis))
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
err = service.verifyBlkPreState(ctx, b.Block)
err = service.verifyBlkPreState(ctx, wrapper.WrappedPhase0BeaconBlock(b.Block))
wanted := "could not reconstruct parent state"
assert.ErrorContains(t, wanted, err)
b.Block.ParentRoot = gRoot[:]
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{Slot: 1})
s, err := v1.InitializeFromProto(&pb.BeaconState{Slot: 1})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b).Block()))
}
func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, StateGen: stategen.New(db, cache.NewStateSummaryCache())}
cfg := &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
signedBlock := testutil.NewBeaconBlock()
require.NoError(t, db.SaveBlock(ctx, signedBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(signedBlock)))
r, err := signedBlock.Block.HashTreeRoot()
require.NoError(t, err)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: []byte{'A'}}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: []byte{'A'}}
st := testutil.NewBeaconState()
require.NoError(t, db.SaveState(ctx, st.Copy(), r))
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveState(ctx, st.Copy(), r))
// Could update
s := testutil.NewBeaconState()
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetCurrentJustifiedCheckpoint(&ethpb.Checkpoint{Epoch: 1, Root: r[:]}))
require.NoError(t, service.updateJustified(context.Background(), s))
@@ -333,28 +345,29 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
service.bestJustifiedCheckpt.Epoch = 2
require.NoError(t, service.updateJustified(context.Background(), s))
assert.Equal(t, uint64(2), service.bestJustifiedCheckpt.Epoch, "Incorrect justified epoch in service")
assert.Equal(t, types.Epoch(2), service.bestJustifiedCheckpt.Epoch, "Incorrect justified epoch in service")
}
func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
require.NoError(t, db.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(db, validGenesisRoot[:])
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
@@ -363,35 +376,36 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
block.Block.ParentRoot = roots[8]
err = service.fillInForkChoiceMissingBlocks(
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
assert.Equal(t, 5, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[4])), "Didn't save node")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[6])), "Didn't save node")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[8])), "Didn't save node")
assert.Equal(t, 5, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[4])), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[6])), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[8])), "Didn't save node")
}
func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
require.NoError(t, db.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(db, validGenesisRoot[:])
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
@@ -400,66 +414,67 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
block.Block.ParentRoot = roots[8]
err = service.fillInForkChoiceMissingBlocks(
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
assert.Equal(t, 5, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, 5, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
// Ensure all roots and their respective blocks exist.
wantedRoots := [][]byte{roots[0], roots[3], roots[4], roots[6], roots[8]}
for i, rt := range wantedRoots {
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(rt)), fmt.Sprintf("Didn't save node: %d", i))
assert.Equal(t, true, service.beaconDB.HasBlock(context.Background(), bytesutil.ToBytes32(rt)))
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(rt)), fmt.Sprintf("Didn't save node: %d", i))
assert.Equal(t, true, service.cfg.BeaconDB.HasBlock(context.Background(), bytesutil.ToBytes32(rt)))
}
}
func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
// Set finalized epoch to 1.
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1}
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
assert.NoError(t, err)
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
// Define a tree branch, slot 63 <- 64 <- 65
b63 := testutil.NewBeaconBlock()
b63.Block.Slot = 63
require.NoError(t, service.beaconDB.SaveBlock(ctx, b63))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b63)))
r63, err := b63.Block.HashTreeRoot()
require.NoError(t, err)
b64 := testutil.NewBeaconBlock()
b64.Block.Slot = 64
b64.Block.ParentRoot = r63[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b64))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b64)))
r64, err := b64.Block.HashTreeRoot()
require.NoError(t, err)
b65 := testutil.NewBeaconBlock()
b65.Block.Slot = 65
b65.Block.ParentRoot = r64[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b65))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b65)))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
err = service.fillInForkChoiceMissingBlocks(
context.Background(), b65.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b65).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// There should be 2 nodes, block 65 and block 64.
assert.Equal(t, 2, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, 2, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
// Block with slot 63 should be in fork choice because it's less than finalized epoch 1.
assert.Equal(t, true, service.forkChoiceStore.HasNode(r63), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r63), "Didn't save node")
}
// blockTree1 constructs the following tree:
@@ -467,7 +482,7 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
// B0 /- B5 - B7
// \- B3 - B4 - B6 - B8
// (B1, and B3 are all from the same slots)
func blockTree1(db db.Database, genesisRoot []byte) ([][]byte, error) {
func blockTree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][]byte, error) {
genesisRoot = bytesutil.PadTo(genesisRoot, 32)
b0 := testutil.NewBeaconBlock()
b0.Block.Slot = 0
@@ -525,26 +540,27 @@ func blockTree1(db db.Database, genesisRoot []byte) ([][]byte, error) {
if err != nil {
return nil, err
}
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
for _, b := range []*ethpb.SignedBeaconBlock{b0, b1, b3, b4, b5, b6, b7, b8} {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
if err := db.SaveBlock(context.Background(), beaconBlock); err != nil {
if err := beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil {
return nil, err
}
if err := db.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, errors.Wrap(err, "could not save state")
}
}
if err := db.SaveState(context.Background(), st.Copy(), r1); err != nil {
if err := beaconDB.SaveState(context.Background(), st.Copy(), r1); err != nil {
return nil, err
}
if err := db.SaveState(context.Background(), st.Copy(), r7); err != nil {
if err := beaconDB.SaveState(context.Background(), st.Copy(), r7); err != nil {
return nil, err
}
if err := db.SaveState(context.Background(), st.Copy(), r8); err != nil {
if err := beaconDB.SaveState(context.Background(), st.Copy(), r8); err != nil {
return nil, err
}
return [][]byte{r0[:], r1[:], nil, r3[:], r4[:], r5[:], r6[:], r7[:], r8[:]}, nil
@@ -554,7 +570,7 @@ func TestCurrentSlot_HandlesOverflow(t *testing.T) {
svc := Service{genesisTime: timeutils.Now().Add(1 * time.Hour)}
slot := svc.CurrentSlot()
require.Equal(t, uint64(0), slot, "Unexpected slot")
require.Equal(t, types.Slot(0), slot, "Unexpected slot")
}
func TestAncestorByDB_CtxErr(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
@@ -568,9 +584,9 @@ func TestAncestorByDB_CtxErr(t *testing.T) {
func TestAncestor_HandleSkipSlot(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
@@ -593,7 +609,7 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, db.SaveBlock(context.Background(), beaconBlock))
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)))
}
// Slots 100 to 200 are skip slots. Requesting root at 150 will yield root at 100. The last physical block.
@@ -638,7 +654,7 @@ func TestAncestor_CanUseForkchoice(t *testing.T) {
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), b.Block.Slot, r, bytesutil.ToBytes32(b.Block.ParentRoot), [32]byte{}, 0, 0)) // Saves blocks to fork choice store.
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), b.Block.Slot, r, bytesutil.ToBytes32(b.Block.ParentRoot), [32]byte{}, 0, 0)) // Saves blocks to fork choice store.
}
r, err := service.ancestor(context.Background(), r200[:], 150)
@@ -650,9 +666,9 @@ func TestAncestor_CanUseForkchoice(t *testing.T) {
func TestAncestor_CanUseDB(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
@@ -675,10 +691,10 @@ func TestAncestor_CanUseDB(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, db.SaveBlock(context.Background(), beaconBlock)) // Saves blocks to DB.
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock))) // Saves blocks to DB.
}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
r, err := service.ancestor(context.Background(), r200[:], 150)
require.NoError(t, err)
@@ -702,7 +718,7 @@ func TestEnsureRootNotZeroHashes(t *testing.T) {
}
func TestFinalizedImpliesNewJustified(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
type args struct {
cachedCheckPoint *ethpb.Checkpoint
@@ -741,14 +757,16 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
},
}
for _, test := range tests {
beaconState := testutil.NewBeaconState()
beaconState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(test.args.stateCheckPoint))
service, err := NewService(ctx, &Config{BeaconDB: db, StateGen: stategen.New(db, sc), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
require.NoError(t, err)
service.justifiedCheckpt = test.args.cachedCheckPoint
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo(test.want.Root, 32)}))
genesisState := testutil.NewBeaconState()
require.NoError(t, service.beaconDB.SaveState(ctx, genesisState, bytesutil.ToBytes32(test.want.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo(test.want.Root, 32)}))
genesisState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, genesisState, bytesutil.ToBytes32(test.want.Root)))
if test.args.diffFinalizedCheckPoint {
b1 := testutil.NewBeaconBlock()
@@ -765,7 +783,7 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), beaconBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(beaconBlock)))
}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: []byte{'c'}, Epoch: 1}
service.justifiedCheckpt.Root = r100[:]
@@ -777,26 +795,25 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
}
func TestVerifyBlkDescendant(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, b))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.Body.Graffiti = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, b1))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
type args struct {
parentRoot [32]byte
finalizedRoot [32]byte
finalizedSlot uint64
}
tests := []struct {
name string
@@ -835,7 +852,7 @@ func TestVerifyBlkDescendant(t *testing.T) {
},
}
for _, tt := range tests {
service, err := NewService(ctx, &Config{BeaconDB: db, StateGen: stategen.New(db, sc), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: tt.args.finalizedRoot[:],
@@ -850,20 +867,20 @@ func TestVerifyBlkDescendant(t *testing.T) {
}
func TestUpdateJustifiedInitSync(t *testing.T) {
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gBlk := testutil.NewBeaconBlock()
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, gBlk))
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(gBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveGenesisBlockRoot(ctx, gRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.beaconDB.SaveState(ctx, beaconState, gRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, beaconState, gRoot))
service.genesisRoot = gRoot
currentCp := &ethpb.Checkpoint{Epoch: 1}
service.justifiedCheckpt = currentCp
@@ -871,11 +888,11 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
require.NoError(t, service.updateJustifiedInitSync(ctx, newCp))
assert.DeepEqual(t, currentCp, service.prevJustifiedCheckpt, "Incorrect previous justified checkpoint")
assert.DeepEqual(t, newCp, service.CurrentJustifiedCheckpt(), "Incorrect current justified checkpoint in cache")
cp, err := service.beaconDB.JustifiedCheckpoint(ctx)
assert.DeepSSZEqual(t, currentCp, service.prevJustifiedCheckpt, "Incorrect previous justified checkpoint")
assert.DeepSSZEqual(t, newCp, service.CurrentJustifiedCheckpt(), "Incorrect current justified checkpoint in cache")
cp, err := service.cfg.BeaconDB.JustifiedCheckpoint(ctx)
require.NoError(t, err)
assert.DeepEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
assert.DeepSSZEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
}
func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
@@ -884,8 +901,103 @@ func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s := testutil.NewBeaconState()
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(1))
service.head = &head{}
service.head = &head{state: (*v1.BeaconState)(nil)}
require.ErrorContains(t, "failed to initialize precompute: nil inner state", service.handleEpochBoundary(ctx, s))
}
func TestHandleEpochBoundary_UpdateFirstSlot(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, _ := testutil.DeterministicGenesisState(t, 1024)
service.head = &head{state: s}
require.NoError(t, s.SetSlot(2*params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, service.handleEpochBoundary(ctx, s))
require.Equal(t, 3*params.BeaconConfig().SlotsPerEpoch, service.nextEpochBoundarySlot)
}
func TestOnBlock_CanFinalize(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
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)
require.NoError(t, err)
gs, keys := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
testState := gs.Copy()
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := testutil.GenerateFullBlock(testState, keys, testutil.DefaultBlockGenConfig(), i)
require.NoError(t, err)
r, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.onBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(blk), r))
testState, err = service.cfg.StateGen.StateByRoot(ctx, r)
require.NoError(t, err)
}
require.Equal(t, types.Epoch(3), service.CurrentJustifiedCheckpt().Epoch)
require.Equal(t, types.Epoch(2), service.FinalizedCheckpt().Epoch)
}
func TestInsertFinalizedDeposits(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
DepositCache: depositCache,
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gs, _ := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
gs = gs.Copy()
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 10}))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
zeroSig := [96]byte{}
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
root := []byte(strconv.Itoa(int(i)))
assert.NoError(t, depositCache.InsertDeposit(ctx, &ethpb.Deposit{Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.FromBytes48([48]byte{}),
WithdrawalCredentials: params.BeaconConfig().ZeroHash[:],
Amount: 0,
Signature: zeroSig[:],
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
}
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
fDeposits := depositCache.FinalizedDeposits(ctx)
assert.Equal(t, 9, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps := depositCache.AllDeposits(ctx, big.NewInt(109))
for _, d := range deps {
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
}
}

View File

@@ -4,12 +4,13 @@ import (
"bytes"
"context"
"fmt"
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
@@ -20,7 +21,7 @@ import (
// AttestationReceiver interface defines the methods of chain service receive and processing new attestations.
type AttestationReceiver interface {
ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error
AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error)
AttestationPreState(ctx context.Context, att *ethpb.Attestation) (iface.BeaconState, error)
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
VerifyFinalizedConsistency(ctx context.Context, root []byte) error
}
@@ -34,21 +35,15 @@ func (s *Service) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Att
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveAttestationNoPubsub")
defer span.End()
_, err := s.onAttestation(ctx, att)
if err != nil {
if err := s.onAttestation(ctx, att); err != nil {
return errors.Wrap(err, "could not process attestation")
}
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
return nil
}
return nil
}
// AttestationPreState returns the pre state of attestation.
func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error) {
func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (iface.BeaconState, error) {
ss, err := helpers.StartSlot(att.Data.Target.Epoch)
if err != nil {
return nil, err
@@ -61,7 +56,18 @@ func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestatio
// VerifyLmdFfgConsistency verifies that attestation's LMD and FFG votes are consistency to each other.
func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestation) error {
return s.verifyLMDFFGConsistent(ctx, a.Data.Target.Epoch, a.Data.Target.Root, a.Data.BeaconBlockRoot)
targetSlot, err := helpers.StartSlot(a.Data.Target.Epoch)
if err != nil {
return err
}
r, err := s.ancestor(ctx, a.Data.BeaconBlockRoot, targetSlot)
if err != nil {
return err
}
if !bytes.Equal(a.Data.Target.Root, r) {
return errors.New("FFG and LMD votes are not consistent")
}
return nil
}
// VerifyFinalizedConsistency verifies input root is consistent with finalized store.
@@ -70,7 +76,7 @@ func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestat
func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) error {
// A canonical root implies the root to has an ancestor that aligns with finalized check point.
// In this case, we could exit early to save on additional computation.
if s.forkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
if s.cfg.ForkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
return nil
}
@@ -90,56 +96,76 @@ func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) e
return nil
}
// This processes attestations from the attestation pool to account for validator votes and fork choice.
func (s *Service) processAttestation(subscribedToStateEvents chan struct{}) {
// This routine processes fork choice attestations from the pool to account for validator votes and fork choice.
func (s *Service) processAttestationsRoutine(subscribedToStateEvents chan<- struct{}) {
// Wait for state to be initialized.
stateChannel := make(chan *feed.Event, 1)
stateSub := s.stateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
subscribedToStateEvents <- struct{}{}
<-stateChannel
stateSub.Unsubscribe()
st := slotutil.GetSlotTicker(s.genesisTime, params.BeaconConfig().SecondsPerSlot)
if s.genesisTime.IsZero() {
log.Warn("ProcessAttestations routine waiting for genesis time")
for s.genesisTime.IsZero() {
time.Sleep(1 * time.Second)
}
log.Warn("Genesis time received, now available to process attestations")
}
st := slotutil.NewSlotTicker(s.genesisTime, params.BeaconConfig().SecondsPerSlot)
for {
select {
case <-s.ctx.Done():
return
case <-st.C():
ctx := s.ctx
atts := s.attPool.ForkchoiceAttestations()
for _, a := range atts {
// Based on the spec, don't process the attestation until the subsequent slot.
// This delays consideration in the fork choice until their slot is in the past.
// https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/fork-choice.md#validate_on_attestation
nextSlot := a.Data.Slot + 1
if err := helpers.VerifySlotTime(uint64(s.genesisTime.Unix()), nextSlot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
continue
}
hasState := s.stateGen.StateSummaryExists(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
hasBlock := s.hasBlock(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
if !(hasState && hasBlock) {
continue
}
if err := s.attPool.DeleteForkchoiceAttestation(a); err != nil {
log.WithError(err).Error("Could not delete fork choice attestation in pool")
}
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime) {
continue
}
if err := s.ReceiveAttestationNoPubsub(ctx, a); err != nil {
log.WithFields(logrus.Fields{
"slot": a.Data.Slot,
"committeeIndex": a.Data.CommitteeIndex,
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.BeaconBlockRoot)),
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.Target.Root)),
"aggregationCount": a.AggregationBits.Count(),
}).WithError(err).Warn("Could not receive attestation in chain service")
}
// Continue when there's no fork choice attestation, there's nothing to process and update head.
// This covers the condition when the node is still initial syncing to the head of the chain.
if s.cfg.AttPool.ForkchoiceAttestationCount() == 0 {
continue
}
s.processAttestations(s.ctx)
if err := s.updateHead(s.ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
}
}
}
}
// This processes fork choice attestations from the pool to account for validator votes and fork choice.
func (s *Service) processAttestations(ctx context.Context) {
atts := s.cfg.AttPool.ForkchoiceAttestations()
for _, a := range atts {
// Based on the spec, don't process the attestation until the subsequent slot.
// This delays consideration in the fork choice until their slot is in the past.
// https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/fork-choice.md#validate_on_attestation
nextSlot := a.Data.Slot + 1
if err := helpers.VerifySlotTime(uint64(s.genesisTime.Unix()), nextSlot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
continue
}
hasState := s.cfg.BeaconDB.HasStateSummary(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
hasBlock := s.hasBlock(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
if !(hasState && hasBlock) {
continue
}
if err := s.cfg.AttPool.DeleteForkchoiceAttestation(a); err != nil {
log.WithError(err).Error("Could not delete fork choice attestation in pool")
}
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime) {
continue
}
if err := s.ReceiveAttestationNoPubsub(ctx, a); err != nil {
log.WithFields(logrus.Fields{
"slot": a.Data.Slot,
"committeeIndex": a.Data.CommitteeIndex,
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.BeaconBlockRoot)),
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.Target.Root)),
"aggregationCount": a.AggregationBits.Count(),
}).WithError(err).Warn("Could not process attestation for fork choice")
}
}
}

View File

@@ -5,21 +5,118 @@ import (
"testing"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/shared/timeutils"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestAttestationCheckPtState_FarFutureSlot(t *testing.T) {
helpers.ClearCache()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService := setupBeaconChain(t, beaconDB)
chainService.genesisTime = time.Now()
e := helpers.MaxSlotBuffer/params.BeaconConfig().SlotsPerEpoch + 1
e := types.Epoch(helpers.MaxSlotBuffer/uint64(params.BeaconConfig().SlotsPerEpoch) + 1)
_, err := chainService.AttestationPreState(context.Background(), &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: e}}})
require.ErrorContains(t, "exceeds max allowed value relative to the local clock", err)
}
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)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
wanted := "FFG and LMD votes are not consistent"
a := testutil.NewAttestation()
a.Data.Target.Epoch = 1
a.Data.Target.Root = []byte{'a'}
a.Data.BeaconBlockRoot = r33[:]
require.ErrorContains(t, wanted, service.VerifyLmdFfgConsistency(context.Background(), a))
}
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)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
a := testutil.NewAttestation()
a.Data.Target.Epoch = 1
a.Data.Target.Root = r32[:]
a.Data.BeaconBlockRoot = r33[:]
err = service.VerifyLmdFfgConsistency(context.Background(), a)
require.NoError(t, err, "Could not verify LMD and FFG votes to be consistent")
}
func TestProcessAttestations_Ok(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
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 = timeutils.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
require.NoError(t, err)
genesisState, pks := testutil.DeterministicGenesisState(t, 64)
require.NoError(t, genesisState.SetGenesisTime(uint64(timeutils.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
atts, err := testutil.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root)
copied := genesisState.Copy()
copied, err = state.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(atts))
service.processAttestations(ctx)
require.Equal(t, 0, len(service.cfg.AttPool.ForkchoiceAttestations()))
require.LogsDoNotContain(t, hook, "Could not process attestation for fork choice")
}

View File

@@ -4,24 +4,24 @@ import (
"context"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// This defines how many epochs since finality the run time will begin to save hot state on to the DB.
var epochsSinceFinalitySaveHotStateDB = 100
var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
// BlockReceiver interface defines the methods of chain service receive and processing new blocks.
type BlockReceiver interface {
ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error
HasInitSyncBlock(root [32]byte) bool
}
@@ -30,10 +30,11 @@ type BlockReceiver interface {
// 1. Validate block, apply state transition and update check points
// 2. Apply fork choice to the processed block
// 3. Save latest head info
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
defer span.End()
blockCopy := stateTrie.CopySignedBeaconBlock(block)
receivedTime := timeutils.Now()
blockCopy := block.Copy()
// Apply state transition on the new block.
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
@@ -43,22 +44,24 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
}
// Update and save head block after fork choice.
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
if !featureconfig.Get().UpdateHeadTimely {
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
}
// Send notification of the processed block to the state feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block().Slot(),
BlockRoot: blockRoot,
SignedBlock: blockCopy,
Verified: true,
},
})
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
Verified: true,
},
})
// Handle post block operations such as attestations and exits.
if err := s.handlePostBlockOperations(blockCopy.Block); err != nil {
if err := s.handlePostBlockOperations(blockCopy.Block()); err != nil {
return err
}
@@ -68,50 +71,14 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
}
// Reports on block and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
// Log block sync status.
logBlockSyncStatus(blockCopy.Block, blockRoot, s.finalizedCheckpt)
// Log state transition data.
logStateTransitionData(blockCopy.Block)
return nil
}
// ReceiveBlockInitialSync processes the input block for the purpose of initial syncing.
// This method should only be used on blocks during initial syncing phase.
func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockNoVerify")
defer span.End()
blockCopy := stateTrie.CopySignedBeaconBlock(block)
// Apply state transition on the new block.
if err := s.onBlockInitialSyncStateTransition(ctx, blockCopy, blockRoot); err != nil {
err := errors.Wrap(err, "could not process block")
traceutil.AnnotateError(span, err)
if err := logBlockSyncStatus(blockCopy.Block(), blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
return err
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
Verified: true,
},
})
// Reports on blockCopy and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
// Log state transition data.
log.WithFields(logrus.Fields{
"slot": blockCopy.Block.Slot,
"attestations": len(blockCopy.Block.Body.Attestations),
"deposits": len(blockCopy.Block.Body.Deposits),
}).Debug("Finished applying state transition")
logStateTransitionData(blockCopy.Block())
return nil
}
@@ -119,7 +86,7 @@ func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.Sign
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
// the state, performing batch verification of all collected signatures and then performing the appropriate
// actions for a block post-transition.
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error {
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
defer span.End()
@@ -132,23 +99,24 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
}
for i, b := range blocks {
blockCopy := stateTrie.CopySignedBeaconBlock(b)
blockCopy := b.Copy()
if err = s.handleBlockAfterBatchVerify(ctx, blockCopy, blkRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
traceutil.AnnotateError(span, err)
return err
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blkRoots[i],
Verified: true,
Slot: blockCopy.Block().Slot(),
BlockRoot: blkRoots[i],
SignedBlock: blockCopy,
Verified: true,
},
})
// Reports on blockCopy and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
@@ -166,25 +134,25 @@ func (s *Service) HasInitSyncBlock(root [32]byte) bool {
return s.hasInitSyncBlock(root)
}
func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
func (s *Service) handlePostBlockOperations(b interfaces.BeaconBlock) error {
// Delete the processed block attestations from attestation pool.
if err := s.deletePoolAtts(b.Body.Attestations); err != nil {
if err := s.deletePoolAtts(b.Body().Attestations()); err != nil {
return err
}
// Add block attestations to the fork choice pool to compute head.
if err := s.attPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body().Attestations()); err != nil {
log.Errorf("Could not save block attestations for fork choice: %v", err)
return nil
}
// Mark block exits as seen so we don't include same ones in future blocks.
for _, e := range b.Body.VoluntaryExits {
s.exitPool.MarkIncluded(e)
for _, e := range b.Body().VoluntaryExits() {
s.cfg.ExitPool.MarkIncluded(e)
}
// Mark attester slashings as seen so we don't include same ones in future blocks.
for _, as := range b.Body.AttesterSlashings {
s.slashingPool.MarkIncludedAttesterSlashing(as)
for _, as := range b.Body().AttesterSlashings() {
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
}
return nil
}
@@ -194,15 +162,15 @@ func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
func (s *Service) checkSaveHotStateDB(ctx context.Context) error {
currentEpoch := helpers.SlotToEpoch(s.CurrentSlot())
// Prevent `sinceFinality` going underflow.
var sinceFinality uint64
var sinceFinality types.Epoch
if currentEpoch > s.finalizedCheckpt.Epoch {
sinceFinality = currentEpoch - s.finalizedCheckpt.Epoch
}
if sinceFinality >= uint64(epochsSinceFinalitySaveHotStateDB) {
s.stateGen.EnableSaveHotStateToDB(ctx)
if sinceFinality >= epochsSinceFinalitySaveHotStateDB {
s.cfg.StateGen.EnableSaveHotStateToDB(ctx)
return nil
}
return s.stateGen.DisableSaveHotStateToDB(ctx)
return s.cfg.StateGen.DisableSaveHotStateToDB(ctx)
}

View File

@@ -6,13 +6,16 @@ import (
"testing"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -25,7 +28,7 @@ func TestService_ReceiveBlock(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot types.Slot) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
@@ -52,7 +55,7 @@ func TestService_ReceiveBlock(t *testing.T) {
if hs := s.head.state.Slot(); hs != 2 {
t.Errorf("Unexpected state slot. Got %d but wanted %d", hs, 2)
}
if bs := s.head.block.Block.Slot; bs != 2 {
if bs := s.head.block.Block().Slot(); bs != 2 {
t.Errorf("Unexpected head block slot. Got %d but wanted %d", bs, 2)
}
},
@@ -72,7 +75,7 @@ func TestService_ReceiveBlock(t *testing.T) {
),
},
check: func(t *testing.T, s *Service) {
if baCount := len(s.attPool.BlockAttestations()); baCount != 2 {
if baCount := len(s.cfg.AttPool.BlockAttestations()); baCount != 2 {
t.Errorf("Did not get the correct number of block attestations saved to the pool. "+
"Got %d but wanted %d", baCount, 2)
}
@@ -92,7 +95,7 @@ func TestService_ReceiveBlock(t *testing.T) {
),
},
check: func(t *testing.T, s *Service) {
pending := s.exitPool.PendingExits(genesis, 1, true /* no limit */)
pending := s.cfg.ExitPool.PendingExits(genesis, 1, true /* no limit */)
if len(pending) != 0 {
t.Errorf(
"Did not mark the correct number of exits. Got %d pending but wanted %d",
@@ -108,7 +111,7 @@ func TestService_ReceiveBlock(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
@@ -117,12 +120,12 @@ func TestService_ReceiveBlock(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, db.SaveState(ctx, genesis, genesisBlockRoot))
require.NoError(t, beaconDB.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
BeaconDB: db,
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
@@ -131,19 +134,19 @@ func TestService_ReceiveBlock(t *testing.T) {
AttPool: attestations.NewPool(),
ExitPool: voluntaryexits.NewPool(),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlock(ctx, tt.args.block, root)
err = s.ReceiveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(tt.args.block), root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
@@ -159,11 +162,11 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
genesis, keys := testutil.DeterministicGenesisState(t, 64)
b, err := testutil.GenerateFullBlock(genesis, keys, testutil.DefaultBlockGenConfig(), 1)
assert.NoError(t, err)
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, db.SaveState(ctx, genesis, genesisBlockRoot))
require.NoError(t, beaconDB.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
BeaconDB: db,
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
@@ -172,14 +175,14 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
AttPool: attestations.NewPool(),
ExitPool: voluntaryexits.NewPool(),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := b.Block.HashTreeRoot()
@@ -187,103 +190,22 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
require.NoError(t, s.ReceiveBlock(ctx, b, root))
require.NoError(t, s.ReceiveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b), root))
wg.Done()
}()
wg.Wait()
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
// Verify fork choice has processed the block. (Genesis block and the new block)
assert.Equal(t, 2, len(s.forkChoiceStore.Nodes()))
}
func TestService_ReceiveBlockInitialSync(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
}
type args struct {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
},
},
{
name: "notifies block processed on state feed",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlockInitialSync(ctx, tt.args.block, root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
}
assert.Equal(t, 2, len(s.cfg.ForkChoiceStore.Nodes()))
}
func TestService_ReceiveBlockBatch(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot types.Slot) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
@@ -304,8 +226,8 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
assert.Equal(t, types.Slot(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, types.Slot(2), s.head.block.Block().Slot(), "Incorrect head block slot")
},
},
{
@@ -314,7 +236,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
@@ -323,32 +245,32 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
genesisBlockRoot, err := genesis.HashTreeRoot(ctx)
require.NoError(t, err)
cfg := &Config{
BeaconDB: db,
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
blks := []*ethpb.SignedBeaconBlock{tt.args.block}
blks := []interfaces.SignedBeaconBlock{wrapper.WrappedPhase0SignedBeaconBlock(tt.args.block)}
roots := [][32]byte{root}
err = s.ReceiveBlockBatch(ctx, blks, roots)
if tt.wantedErr != "" {
@@ -368,18 +290,18 @@ func TestService_HasInitSyncBlock(t *testing.T) {
if s.HasInitSyncBlock(r) {
t.Error("Should not have block")
}
s.saveInitSyncBlock(r, testutil.NewBeaconBlock())
s.saveInitSyncBlock(r, wrapper.WrappedPhase0SignedBeaconBlock(testutil.NewBeaconBlock()))
if !s.HasInitSyncBlock(r) {
t.Error("Should have block")
}
}
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
st := params.BeaconConfig().SlotsPerEpoch * uint64(epochsSinceFinalitySaveHotStateDB)
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{}
@@ -388,9 +310,9 @@ func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
}
func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
@@ -401,9 +323,9 @@ func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
}
func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 10000000}
s.genesisTime = time.Now()

View File

@@ -1,6 +1,5 @@
// Package blockchain defines the life-cycle of the blockchain at the core of
// eth2, including processing of new blocks and attestations using casper
// proof of stake.
// Ethereum, including processing of new blocks and attestations using proof of stake.
package blockchain
import (
@@ -11,16 +10,14 @@ import (
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
f "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
@@ -28,10 +25,13 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"github.com/sirupsen/logrus"
@@ -45,58 +45,44 @@ const headSyncMinEpochsAfterCheckpoint = 128
// Service represents a service that handles the internal
// logic of managing the full PoS beacon chain.
type Service struct {
cfg *Config
ctx context.Context
cancel context.CancelFunc
beaconDB db.HeadAccessDatabase
depositCache *depositcache.DepositCache
chainStartFetcher powchain.ChainStartFetcher
attPool attestations.Pool
slashingPool *slashings.Pool
exitPool *voluntaryexits.Pool
genesisTime time.Time
p2p p2p.Broadcaster
maxRoutines int
head *head
headLock sync.RWMutex
stateNotifier statefeed.Notifier
genesisRoot [32]byte
forkChoiceStore f.ForkChoicer
justifiedCheckpt *ethpb.Checkpoint
prevJustifiedCheckpt *ethpb.Checkpoint
bestJustifiedCheckpt *ethpb.Checkpoint
finalizedCheckpt *ethpb.Checkpoint
prevFinalizedCheckpt *ethpb.Checkpoint
nextEpochBoundarySlot uint64
nextEpochBoundarySlot types.Slot
boundaryRoots [][32]byte
checkpointStateCache *cache.CheckpointStateCache
stateGen *stategen.State
opsService *attestations.Service
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
initSyncBlocks map[[32]byte]interfaces.SignedBeaconBlock
initSyncBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
wsEpoch uint64
wsRoot []byte
wsVerified bool
}
// Config options for the service.
type Config struct {
BeaconBlockBuf int
ChainStartFetcher powchain.ChainStartFetcher
BeaconDB db.HeadAccessDatabase
DepositCache *depositcache.DepositCache
AttPool attestations.Pool
ExitPool *voluntaryexits.Pool
SlashingPool *slashings.Pool
P2p p2p.Broadcaster
MaxRoutines int
StateNotifier statefeed.Notifier
ForkChoiceStore f.ForkChoicer
OpsService *attestations.Service
StateGen *stategen.State
WspBlockRoot []byte
WspEpoch uint64
BeaconBlockBuf int
ChainStartFetcher powchain.ChainStartFetcher
BeaconDB db.HeadAccessDatabase
DepositCache *depositcache.DepositCache
AttPool attestations.Pool
ExitPool voluntaryexits.PoolManager
SlashingPool slashings.PoolManager
P2p p2p.Broadcaster
MaxRoutines int
StateNotifier statefeed.Notifier
ForkChoiceStore f.ForkChoicer
AttService *attestations.Service
StateGen *stategen.State
WeakSubjectivityCheckpt *ethpb.Checkpoint
}
// NewService instantiates a new block service instance that will
@@ -104,26 +90,13 @@ type Config struct {
func NewService(ctx context.Context, cfg *Config) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
return &Service{
cfg: cfg,
ctx: ctx,
cancel: cancel,
beaconDB: cfg.BeaconDB,
depositCache: cfg.DepositCache,
chainStartFetcher: cfg.ChainStartFetcher,
attPool: cfg.AttPool,
exitPool: cfg.ExitPool,
slashingPool: cfg.SlashingPool,
p2p: cfg.P2p,
maxRoutines: cfg.MaxRoutines,
stateNotifier: cfg.StateNotifier,
forkChoiceStore: cfg.ForkChoiceStore,
boundaryRoots: [][32]byte{},
checkpointStateCache: cache.NewCheckpointStateCache(),
opsService: cfg.OpsService,
stateGen: cfg.StateGen,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
justifiedBalances: make([]uint64, 0),
wsEpoch: cfg.WspEpoch,
wsRoot: cfg.WspBlockRoot,
}, nil
}
@@ -132,7 +105,7 @@ 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.beaconDB.FinalizedCheckpoint(s.ctx)
cp, err := s.cfg.BeaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
@@ -142,18 +115,18 @@ func (s *Service) Start() {
// 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.beaconDB.GenesisBlock(s.ctx)
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if genesisBlock != nil {
r, err = genesisBlock.Block.HashTreeRoot()
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.stateGen.StateByRoot(s.ctx, r)
beaconState, err := s.cfg.StateGen.StateByRoot(s.ctx, r)
if err != nil {
log.Fatalf("Could not fetch beacon state by root: %v", err)
}
@@ -162,52 +135,58 @@ func (s *Service) Start() {
attestationProcessorSubscribed := make(chan struct{}, 1)
// If the chain has already been initialized, simply start the block processing routine.
if beaconState != nil {
if beaconState != nil && !beaconState.IsNil() {
log.Info("Blockchain data already exists in DB, initializing...")
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
s.opsService.SetGenesisTime(beaconState.GenesisTime())
s.cfg.AttService.SetGenesisTime(beaconState.GenesisTime())
if err := s.initializeChainInfo(s.ctx); err != nil {
log.Fatalf("Could not set up chain info: %v", err)
}
// We start a counter to genesis, if needed.
gState, err := s.beaconDB.GenesisState(s.ctx)
gState, err := s.cfg.BeaconDB.GenesisState(s.ctx)
if err != nil {
log.Fatalf("Could not retrieve genesis state: %v", err)
}
go slotutil.CountdownToGenesis(s.ctx, s.genesisTime, uint64(gState.NumValidators()))
gRoot, err := gState.HashTreeRoot(s.ctx)
if err != nil {
log.Fatalf("Could not hash tree root genesis state: %v", err)
}
go slotutil.CountdownToGenesis(s.ctx, s.genesisTime, uint64(gState.NumValidators()), gRoot)
justifiedCheckpoint, err := s.beaconDB.JustifiedCheckpoint(s.ctx)
justifiedCheckpoint, err := s.cfg.BeaconDB.JustifiedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get justified checkpoint: %v", err)
}
finalizedCheckpoint, err := s.beaconDB.FinalizedCheckpoint(s.ctx)
finalizedCheckpoint, err := s.cfg.BeaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get finalized checkpoint: %v", err)
}
// Resume fork choice.
s.justifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.justifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
if err := s.cacheJustifiedStateBalances(s.ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))); err != nil {
log.Fatalf("Could not cache justified state balances: %v", err)
}
s.prevJustifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = stateTrie.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = stateTrie.CopyCheckpoint(finalizedCheckpoint)
s.prevJustifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = copyutil.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = copyutil.CopyCheckpoint(finalizedCheckpoint)
s.resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint)
ss, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
log.Fatalf("Could not get start slot of finalized epoch: %v", err)
}
h := s.headBlock().Block
log.WithFields(logrus.Fields{
"startSlot": ss,
"endSlot": h.Slot,
}).Info("Loading blocks to fork choice store, this may take a while.")
if err := s.fillInForkChoiceMissingBlocks(s.ctx, h, s.finalizedCheckpt, s.justifiedCheckpt); err != nil {
log.Fatalf("Could not fill in fork choice store missing blocks: %v", err)
h := s.headBlock().Block()
if h.Slot() > ss {
log.WithFields(logrus.Fields{
"startSlot": ss,
"endSlot": h.Slot(),
}).Info("Loading blocks to fork choice store, this may take a while.")
if err := s.fillInForkChoiceMissingBlocks(s.ctx, h, s.finalizedCheckpt, s.justifiedCheckpt); err != nil {
log.Fatalf("Could not fill in fork choice store missing blocks: %v", err)
}
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
@@ -215,7 +194,7 @@ func (s *Service) Start() {
log.Fatalf("Could not verify weak subjectivity checkpoint: %v", err)
}
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Initialized,
Data: &statefeed.InitializedData{
StartTime: s.genesisTime,
@@ -224,13 +203,13 @@ func (s *Service) Start() {
})
} else {
log.Info("Waiting to reach the validator deposit threshold to start the beacon chain...")
if s.chainStartFetcher == nil {
if s.cfg.ChainStartFetcher == nil {
log.Fatal("Not configured web3Service for POW chain")
return // return need for TestStartUninitializedChainWithoutConfigPOWChain.
}
go func() {
stateChannel := make(chan *feed.Event, 1)
stateSub := s.stateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
<-attestationProcessorSubscribed
for {
@@ -257,23 +236,27 @@ func (s *Service) Start() {
}()
}
go s.processAttestation(attestationProcessorSubscribed)
go s.processAttestationsRoutine(attestationProcessorSubscribed)
}
// processChainStartTime initializes a series of deposits from the ChainStart deposits in the eth1
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Time) {
preGenesisState := s.chainStartFetcher.PreGenesisState()
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState, s.chainStartFetcher.ChainStartEth1Data())
preGenesisState := s.cfg.ChainStartFetcher.PreGenesisState()
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState, s.cfg.ChainStartFetcher.ChainStartEth1Data())
if err != nil {
log.Fatalf("Could not initialize beacon chain: %v", err)
}
// We start a counter to genesis, if needed.
go slotutil.CountdownToGenesis(ctx, genesisTime, uint64(initializedState.NumValidators()))
gRoot, err := initializedState.HashTreeRoot(s.ctx)
if err != nil {
log.Fatalf("Could not hash tree root genesis state: %v", err)
}
go slotutil.CountdownToGenesis(ctx, genesisTime, uint64(initializedState.NumValidators()), gRoot)
// We send out a state initialized event to the rest of the services
// running in the beacon node.
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Initialized,
Data: &statefeed.InitializedData{
StartTime: genesisTime,
@@ -288,8 +271,8 @@ func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Ti
func (s *Service) initializeBeaconChain(
ctx context.Context,
genesisTime time.Time,
preGenesisState *stateTrie.BeaconState,
eth1data *ethpb.Eth1Data) (*stateTrie.BeaconState, error) {
preGenesisState iface.BeaconState,
eth1data *ethpb.Eth1Data) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.Service.initializeBeaconChain")
defer span.End()
s.genesisTime = genesisTime
@@ -307,17 +290,17 @@ func (s *Service) initializeBeaconChain(
log.Info("Initialized beacon chain genesis state")
// Clear out all pre-genesis data now that the state is initialized.
s.chainStartFetcher.ClearPreGenesisData()
s.cfg.ChainStartFetcher.ClearPreGenesisData()
// Update committee shuffled indices for genesis epoch.
if err := helpers.UpdateCommitteeCache(genesisState, 0 /* genesis epoch */); err != nil {
return nil, err
}
if err := helpers.UpdateProposerIndicesInCache(genesisState, 0 /* genesis epoch */); err != nil {
if err := helpers.UpdateProposerIndicesInCache(genesisState); err != nil {
return nil, err
}
s.opsService.SetGenesisTime(genesisState.GenesisTime())
s.cfg.AttService.SetGenesisTime(genesisState.GenesisTime())
return genesisState, nil
}
@@ -326,14 +309,14 @@ func (s *Service) initializeBeaconChain(
func (s *Service) Stop() error {
defer s.cancel()
if s.stateGen != nil && s.head != nil && s.head.state != nil {
if err := s.stateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
if s.cfg.StateGen != nil && s.head != nil && s.head.state != nil {
if err := s.cfg.StateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
return err
}
}
// Save initial sync cached blocks to the DB before stop.
return s.beaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks())
return s.cfg.BeaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks())
}
// Status always returns nil unless there is an error condition that causes
@@ -342,61 +325,43 @@ func (s *Service) Status() error {
if s.genesisRoot == params.BeaconConfig().ZeroHash {
return errors.New("genesis state has not been created")
}
if runtime.NumGoroutine() > s.maxRoutines {
if runtime.NumGoroutine() > s.cfg.MaxRoutines {
return fmt.Errorf("too many goroutines %d", runtime.NumGoroutine())
}
return nil
}
// This gets called when beacon chain is first initialized to save genesis data (state, block, and more) in db.
func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.BeaconState) error {
stateRoot, err := genesisState.HashTreeRoot(ctx)
if err != nil {
return err
func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.BeaconState) error {
if err := s.cfg.BeaconDB.SaveGenesisData(ctx, genesisState); err != nil {
return errors.Wrap(err, "could not save genesis data")
}
genesisBlk := blocks.NewGenesisBlock(stateRoot[:])
genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
if err != nil || genesisBlk == nil || genesisBlk.IsNil() {
return fmt.Errorf("could not load genesis block: %v", err)
}
genesisBlkRoot, err := genesisBlk.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get genesis block root")
}
s.genesisRoot = genesisBlkRoot
if err := s.beaconDB.SaveBlock(ctx, genesisBlk); err != nil {
return errors.Wrap(err, "could not save genesis block")
}
if err := s.beaconDB.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis state")
}
if err := s.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: 0,
Root: genesisBlkRoot[:],
}); err != nil {
return err
}
s.stateGen.SaveFinalizedState(0, genesisBlkRoot, genesisState)
if err := s.beaconDB.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save head block root")
}
if err := s.beaconDB.SaveGenesisBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis block root")
}
s.cfg.StateGen.SaveFinalizedState(0 /*slot*/, genesisBlkRoot, genesisState)
// Finalized checkpoint at genesis is a zero hash.
genesisCheckpoint := genesisState.FinalizedCheckpoint()
s.justifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.justifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
if err := s.cacheJustifiedStateBalances(ctx, genesisBlkRoot); err != nil {
return err
}
s.prevJustifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.prevJustifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
if err := s.forkChoiceStore.ProcessBlock(ctx,
genesisBlk.Block.Slot,
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
genesisBlk.Block().Slot(),
genesisBlkRoot,
params.BeaconConfig().ZeroHash,
[32]byte{},
@@ -406,26 +371,25 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.B
}
s.setHead(genesisBlkRoot, genesisBlk, genesisState)
return nil
}
// This gets called to initialize chain info variables using the finalized checkpoint stored in DB
func (s *Service) initializeChainInfo(ctx context.Context) error {
genesisBlock, err := s.beaconDB.GenesisBlock(ctx)
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not get genesis block from db")
}
if genesisBlock == nil {
if genesisBlock == nil || genesisBlock.IsNil() {
return errors.New("no genesis block in db")
}
genesisBlkRoot, err := genesisBlock.Block.HashTreeRoot()
genesisBlkRoot, err := genesisBlock.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get signing root of genesis block")
}
s.genesisRoot = genesisBlkRoot
finalized, err := s.beaconDB.FinalizedCheckpoint(ctx)
finalized, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized checkpoint from db")
}
@@ -435,37 +399,37 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
return errors.New("no finalized epoch in the database")
}
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
var finalizedState *stateTrie.BeaconState
var finalizedState iface.BeaconState
finalizedState, err = s.stateGen.Resume(ctx)
finalizedState, err = s.cfg.StateGen.Resume(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
if flags.Get().HeadSync {
headBlock, err := s.beaconDB.HeadBlock(ctx)
headBlock, err := s.cfg.BeaconDB.HeadBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not retrieve head block")
}
headEpoch := helpers.SlotToEpoch(headBlock.Block.Slot)
var epochsSinceFinality uint64
headEpoch := helpers.SlotToEpoch(headBlock.Block().Slot())
var epochsSinceFinality types.Epoch
if headEpoch > finalized.Epoch {
epochsSinceFinality = headEpoch - finalized.Epoch
}
// Head sync when node is far enough beyond known finalized epoch,
// this becomes really useful during long period of non-finality.
if epochsSinceFinality >= headSyncMinEpochsAfterCheckpoint {
headRoot, err := headBlock.Block.HashTreeRoot()
headRoot, err := headBlock.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not hash head block")
}
finalizedState, err := s.stateGen.Resume(ctx)
finalizedState, err := s.cfg.StateGen.Resume(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
log.Infof("Regenerating state from the last checkpoint at slot %d to current head slot of %d."+
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block.Slot)
headState, err := s.stateGen.StateByRoot(ctx, headRoot)
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block().Slot())
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
if err != nil {
return errors.Wrap(err, "could not retrieve head state")
}
@@ -478,12 +442,12 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
}
}
finalizedBlock, err := s.beaconDB.Block(ctx, finalizedRoot)
finalizedBlock, err := s.cfg.BeaconDB.Block(ctx, finalizedRoot)
if err != nil {
return errors.Wrap(err, "could not get finalized block from db")
}
if finalizedState == nil || finalizedBlock == nil {
if finalizedState == nil || finalizedState.IsNil() || finalizedBlock == nil || finalizedBlock.IsNil() {
return errors.New("finalized state and block can't be nil")
}
s.setHead(finalizedRoot, finalizedBlock, finalizedState)
@@ -495,7 +459,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
// information to fork choice service to initializes fork choice store.
func (s *Service) resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint *ethpb.Checkpoint) {
store := protoarray.New(justifiedCheckpoint.Epoch, finalizedCheckpoint.Epoch, bytesutil.ToBytes32(finalizedCheckpoint.Root))
s.forkChoiceStore = store
s.cfg.ForkChoiceStore = store
}
// This returns true if block has been processed before. Two ways to verify the block has been processed:
@@ -503,9 +467,9 @@ func (s *Service) resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint *eth
// 2.) Check DB.
// Checking 1.) is ten times faster than checking 2.)
func (s *Service) hasBlock(ctx context.Context, root [32]byte) bool {
if s.forkChoiceStore.HasNode(root) {
if s.cfg.ForkChoiceStore.HasNode(root) {
return true
}
return s.beaconDB.HasBlock(ctx, root)
return s.cfg.BeaconDB.HasBlock(ctx, root)
}

View File

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

View File

@@ -8,24 +8,26 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
protodb "github.com/prysmaticlabs/prysm/proto/beacon/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -33,6 +35,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
logTest "github.com/sirupsen/logrus/hooks/test"
"google.golang.org/protobuf/proto"
)
type mockBeaconNode struct {
@@ -63,14 +66,16 @@ func (mb *mockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, _ *
var _ p2p.Broadcaster = (*mockBroadcaster)(nil)
func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummaryCache) *Service {
func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
endpoint := "http://127.0.0.1"
ctx := context.Background()
var web3Service *powchain.Service
var err error
bState, _ := testutil.DeterministicGenesisState(t, 10)
pbState, err := v1.ProtobufBeaconState(bState.InnerStateUnsafe())
require.NoError(t, err)
err = beaconDB.SavePowchainData(ctx, &protodb.ETH1ChainData{
BeaconState: bState.InnerStateUnsafe(),
BeaconState: pbState,
Trie: &protodb.SparseMerkleTrie{},
CurrentEth1Data: &protodb.LatestETH1Data{
BlockHash: make([]byte, 32),
@@ -87,12 +92,12 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
require.NoError(t, err)
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
BeaconDB: beaconDB,
HTTPEndPoint: endpoint,
HttpEndpoints: []string{endpoint},
DepositContract: common.Address{},
})
require.NoError(t, err, "Unable to set up web3 service")
opsService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
attService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
require.NoError(t, err)
depositCache, err := depositcache.New()
@@ -106,9 +111,9 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
P2p: &mockBroadcaster{},
StateNotifier: &mockBeaconNode{},
AttPool: attestations.NewPool(),
StateGen: stategen.New(beaconDB, sc),
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, params.BeaconConfig().ZeroHash),
OpsService: opsService,
AttService: attService,
}
// Safe a state in stategen to purposes of testing a service stop / shutdown.
@@ -124,21 +129,22 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
func TestChainStartStop_Initialized(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService := setupBeaconChain(t, beaconDB)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(1))
require.NoError(t, db.SaveState(ctx, s, blkRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
require.NoError(t, beaconDB.SaveState(ctx, s, blkRoot))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, blkRoot))
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[:]}))
// Test the start function.
chainService.Start()
@@ -153,18 +159,19 @@ func TestChainStartStop_Initialized(t *testing.T) {
func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService := setupBeaconChain(t, beaconDB)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
require.NoError(t, db.SaveState(ctx, s, blkRoot))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
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[:]}))
// Test the start function.
chainService.Start()
@@ -178,10 +185,10 @@ func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
func TestChainService_InitializeBeaconChain(t *testing.T) {
helpers.ClearCache()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
bc := setupBeaconChain(t, db, sc)
bc := setupBeaconChain(t, beaconDB)
var err error
// Set up 10 deposits pre chain start for validators to register
@@ -221,20 +228,21 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
func TestChainService_CorrectGenesisRoots(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService := setupBeaconChain(t, beaconDB)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(0))
require.NoError(t, db.SaveState(ctx, s, blkRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
require.NoError(t, beaconDB.SaveState(ctx, s, blkRoot))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
// Test the start function.
chainService.Start()
@@ -247,36 +255,37 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
}
func TestChainService_InitializeChainInfo(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
genesis := testutil.NewBeaconBlock()
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
headBlock := testutil.NewBeaconBlock()
headBlock.Block.Slot = finalizedSlot
headBlock.Block.ParentRoot = bytesutil.PadTo(genesisRoot[:], 32)
headState := testutil.NewBeaconState()
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(finalizedSlot))
require.NoError(t, headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]))
headRoot, err := headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, headState, headRoot))
require.NoError(t, db.SaveState(ctx, headState, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, headBlock))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{beaconDB: db, stateGen: stategen.New(db, sc)}
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)))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headBlock, headBlk, "Head block incorrect")
assert.DeepEqual(t, headBlock, headBlk.Proto(), "Head block incorrect")
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, c.HeadSlot(), headBlock.Block.Slot, "Head slot incorrect")
r, err := c.HeadRoot(context.Background())
require.NoError(t, err)
@@ -287,34 +296,35 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
}
func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
genesis := testutil.NewBeaconBlock()
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
headBlock := testutil.NewBeaconBlock()
headBlock.Block.Slot = finalizedSlot
headBlock.Block.ParentRoot = bytesutil.PadTo(genesisRoot[:], 32)
headState := testutil.NewBeaconState()
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(finalizedSlot))
require.NoError(t, headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]))
headRoot, err := headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, headState, headRoot))
require.NoError(t, db.SaveState(ctx, headState, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, headBlock))
c := &Service{beaconDB: db, stateGen: stategen.New(db, sc)}
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)}}
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
assert.DeepEqual(t, genesis, c.head.block)
assert.DeepEqual(t, genesis, c.head.block.Proto())
}
func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
@@ -328,21 +338,21 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
hook := logTest.NewGlobal()
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
genesisBlock := testutil.NewBeaconBlock()
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, genesisBlock))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlock)))
finalizedBlock := testutil.NewBeaconBlock()
finalizedBlock.Block.Slot = finalizedSlot
finalizedBlock.Block.ParentRoot = genesisRoot[:]
finalizedRoot, err := finalizedBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, finalizedBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(finalizedBlock)))
// Set head slot close to the finalization point, no head sync is triggered.
headBlock := testutil.NewBeaconBlock()
@@ -350,29 +360,30 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
headBlock.Block.ParentRoot = finalizedRoot[:]
headRoot, err := headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(headBlock)))
headState := testutil.NewBeaconState()
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(headBlock.Block.Slot))
require.NoError(t, headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]))
require.NoError(t, db.SaveState(ctx, headState, genesisRoot))
require.NoError(t, db.SaveState(ctx, headState, finalizedRoot))
require.NoError(t, db.SaveState(ctx, headState, headRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, headRoot))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, finalizedRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{
Epoch: helpers.SlotToEpoch(finalizedBlock.Block.Slot),
Root: finalizedRoot[:],
}))
c := &Service{beaconDB: db, stateGen: stategen.New(db, sc)}
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)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Since head sync is not triggered, chain is initialized to the last finalization checkpoint.
assert.DeepEqual(t, finalizedBlock, c.head.block)
assert.DeepEqual(t, finalizedBlock, c.head.block.Proto())
assert.LogsContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
assert.LogsDoNotContain(t, hook, "Regenerating state from the last checkpoint at slot")
@@ -382,57 +393,57 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
headBlock.Block.ParentRoot = finalizedRoot[:]
headRoot, err = headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, headBlock))
require.NoError(t, db.SaveState(ctx, headState, headRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, headRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(headBlock)))
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
hook.Reset()
require.NoError(t, c.initializeChainInfo(ctx))
s, err = c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Head slot is far beyond the latest finalized checkpoint, head sync is triggered.
assert.DeepEqual(t, headBlock, c.head.block)
assert.DeepEqual(t, headBlock, c.head.block.Proto())
assert.LogsContain(t, hook, "Regenerating state from the last checkpoint at slot 225")
assert.LogsDoNotContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
}
func TestChainService_SaveHeadNoDB(t *testing.T) {
db, sc := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
s := &Service{
beaconDB: db,
stateGen: stategen.New(db, sc),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
r, err := b.HashTreeRoot()
blk := testutil.NewBeaconBlock()
blk.Block.Slot = 1
r, err := blk.HashTreeRoot()
require.NoError(t, err)
newState := testutil.NewBeaconState()
require.NoError(t, s.stateGen.SaveState(ctx, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, b, r, newState))
newState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.cfg.StateGen.SaveState(ctx, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, wrapper.WrappedPhase0SignedBeaconBlock(blk), r, newState))
newB, err := s.beaconDB.HeadBlock(ctx)
newB, err := s.cfg.BeaconDB.HeadBlock(ctx)
require.NoError(t, err)
if reflect.DeepEqual(newB, b) {
if reflect.DeepEqual(newB, blk) {
t.Error("head block should not be equal")
}
}
func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: db,
}
block := testutil.NewBeaconBlock()
r, err := block.Block.HashTreeRoot()
require.NoError(t, err)
state := testutil.NewBeaconState()
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, state))
beaconState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block).Block(), r, beaconState))
assert.Equal(t, false, s.hasBlock(ctx, [32]byte{}), "Should not have block")
assert.Equal(t, true, s.hasBlock(ctx, r), "Should have block")
@@ -440,56 +451,69 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
func TestServiceStop_SaveCachedBlocks(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
ctx: ctx,
cancel: cancel,
beaconDB: db,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
}
b := testutil.NewBeaconBlock()
r, err := b.Block.HashTreeRoot()
block := testutil.NewBeaconBlock()
r, err := block.Block.HashTreeRoot()
require.NoError(t, err)
s.saveInitSyncBlock(r, b)
s.saveInitSyncBlock(r, wrapper.WrappedPhase0SignedBeaconBlock(block))
require.NoError(t, s.Stop())
require.Equal(t, true, s.beaconDB.HasBlock(ctx, r))
require.Equal(t, true, s.cfg.BeaconDB.HasBlock(ctx, r))
}
func TestProcessChainStartTime_ReceivedFeed(t *testing.T) {
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
stateChannel := make(chan *feed.Event, 1)
stateSub := service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
service.processChainStartTime(context.Background(), time.Now())
stateEvent := <-stateChannel
require.Equal(t, int(stateEvent.Type), statefeed.Initialized)
_, ok := stateEvent.Data.(*statefeed.InitializedData)
require.Equal(t, true, ok)
}
func BenchmarkHasBlockDB(b *testing.B) {
db, _ := testDB.SetupDB(b)
beaconDB := testDB.SetupDB(b)
ctx := context.Background()
s := &Service{
beaconDB: db,
cfg: &Config{BeaconDB: beaconDB},
}
block := testutil.NewBeaconBlock()
require.NoError(b, s.beaconDB.SaveBlock(ctx, block))
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
b.ResetTimer()
for i := 0; i < b.N; i++ {
require.Equal(b, true, s.beaconDB.HasBlock(ctx, r), "Block is not in DB")
require.Equal(b, true, s.cfg.BeaconDB.HasBlock(ctx, r), "Block is not in DB")
}
}
func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
ctx := context.Background()
db, _ := testDB.SetupDB(b)
beaconDB := testDB.SetupDB(b)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: db,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}}
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}}
state, err := beaconstate.InitializeFromProto(bs)
beaconState, err := v1.InitializeFromProto(bs)
require.NoError(b, err)
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, state))
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block).Block(), r, beaconState))
b.ResetTimer()
for i := 0; i < b.N; i++ {
require.Equal(b, true, s.forkChoiceStore.HasNode(r), "Block is not in fork choice store")
require.Equal(b, true, s.cfg.ForkChoiceStore.HasNode(r), "Block is not in fork choice store")
}
}

View File

@@ -18,12 +18,16 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/interfaces:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
"//shared/params:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

View File

@@ -9,7 +9,7 @@ import (
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
blockfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/block"
@@ -18,8 +18,12 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
@@ -27,13 +31,13 @@ import (
// ChainService defines the mock interface for testing
type ChainService struct {
State *stateTrie.BeaconState
State iface.BeaconState
Root []byte
Block *ethpb.SignedBeaconBlock
Block interfaces.SignedBeaconBlock
FinalizedCheckPoint *ethpb.Checkpoint
CurrentJustifiedCheckPoint *ethpb.Checkpoint
PreviousJustifiedCheckPoint *ethpb.Checkpoint
BlocksReceived []*ethpb.SignedBeaconBlock
BlocksReceived []interfaces.SignedBeaconBlock
Balance *precompute.Balance
Genesis time.Time
ValidatorsRoot [32]byte
@@ -47,22 +51,23 @@ type ChainService struct {
ValidAttestation bool
ForkChoiceStore *protoarray.Store
VerifyBlkDescendantErr error
Slot *types.Slot // Pointer because 0 is a useful value, so checking against it can be incorrect.
}
// StateNotifier mocks the same method in the chain service.
func (ms *ChainService) StateNotifier() statefeed.Notifier {
if ms.stateNotifier == nil {
ms.stateNotifier = &MockStateNotifier{}
func (s *ChainService) StateNotifier() statefeed.Notifier {
if s.stateNotifier == nil {
s.stateNotifier = &MockStateNotifier{}
}
return ms.stateNotifier
return s.stateNotifier
}
// BlockNotifier mocks the same method in the chain service.
func (ms *ChainService) BlockNotifier() blockfeed.Notifier {
if ms.blockNotifier == nil {
ms.blockNotifier = &MockBlockNotifier{}
func (s *ChainService) BlockNotifier() blockfeed.Notifier {
if s.blockNotifier == nil {
s.blockNotifier = &MockBlockNotifier{}
}
return ms.blockNotifier
return s.blockNotifier
}
// MockBlockNotifier mocks the block notifier.
@@ -71,11 +76,11 @@ type MockBlockNotifier struct {
}
// BlockFeed returns a block feed.
func (msn *MockBlockNotifier) BlockFeed() *event.Feed {
if msn.feed == nil {
msn.feed = new(event.Feed)
func (mbn *MockBlockNotifier) BlockFeed() *event.Feed {
if mbn.feed == nil {
mbn.feed = new(event.Feed)
}
return msn.feed
return mbn.feed
}
// MockStateNotifier mocks the state notifier.
@@ -124,11 +129,11 @@ func (msn *MockStateNotifier) StateFeed() *event.Feed {
}
// OperationNotifier mocks the same method in the chain service.
func (ms *ChainService) OperationNotifier() opfeed.Notifier {
if ms.opNotifier == nil {
ms.opNotifier = &MockOperationNotifier{}
func (s *ChainService) OperationNotifier() opfeed.Notifier {
if s.opNotifier == nil {
s.opNotifier = &MockOperationNotifier{}
}
return ms.opNotifier
return s.opNotifier
}
// MockOperationNotifier mocks the operation notifier.
@@ -145,224 +150,227 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
}
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &v1.BeaconState{}
}
if !bytes.Equal(ms.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", ms.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := ms.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
if ms.DB != nil {
if err := ms.DB.SaveBlock(ctx, block); err != nil {
if s.DB != nil {
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
ms.Root = signingRoot[:]
ms.Block = block
s.Root = signingRoot[:]
s.Block = block
return nil
}
// ReceiveBlockBatch processes blocks in batches from initial-sync.
func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, _ [][32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock, _ [][32]byte) error {
if s.State == nil {
s.State = &v1.BeaconState{}
}
for _, block := range blks {
if !bytes.Equal(ms.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", ms.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := ms.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
if ms.DB != nil {
if err := ms.DB.SaveBlock(ctx, block); err != nil {
if s.DB != nil {
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
ms.Root = signingRoot[:]
ms.Block = block
s.Root = signingRoot[:]
s.Block = block
}
return nil
}
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
func (s *ChainService) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &v1.BeaconState{}
}
if !bytes.Equal(ms.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", ms.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := ms.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
if ms.DB != nil {
if err := ms.DB.SaveBlock(ctx, block); err != nil {
if s.DB != nil {
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
ms.Root = signingRoot[:]
ms.Block = block
s.Root = signingRoot[:]
s.Block = block
return nil
}
// HeadSlot mocks HeadSlot method in chain service.
func (ms *ChainService) HeadSlot() uint64 {
if ms.State == nil {
func (s *ChainService) HeadSlot() types.Slot {
if s.State == nil {
return 0
}
return ms.State.Slot()
return s.State.Slot()
}
// HeadRoot mocks HeadRoot method in chain service.
func (ms *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
if len(ms.Root) > 0 {
return ms.Root, nil
func (s *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
if len(s.Root) > 0 {
return s.Root, nil
}
return make([]byte, 32), nil
}
// HeadBlock mocks HeadBlock method in chain service.
func (ms *ChainService) HeadBlock(context.Context) (*ethpb.SignedBeaconBlock, error) {
return ms.Block, nil
func (s *ChainService) HeadBlock(context.Context) (interfaces.SignedBeaconBlock, error) {
return s.Block, nil
}
// HeadState mocks HeadState method in chain service.
func (ms *ChainService) HeadState(context.Context) (*stateTrie.BeaconState, error) {
return ms.State, nil
func (s *ChainService) HeadState(context.Context) (iface.BeaconState, error) {
return s.State, nil
}
// CurrentFork mocks HeadState method in chain service.
func (ms *ChainService) CurrentFork() *pb.Fork {
return ms.Fork
func (s *ChainService) CurrentFork() *pb.Fork {
return s.Fork
}
// FinalizedCheckpt mocks FinalizedCheckpt method in chain service.
func (ms *ChainService) FinalizedCheckpt() *ethpb.Checkpoint {
return ms.FinalizedCheckPoint
func (s *ChainService) FinalizedCheckpt() *ethpb.Checkpoint {
return s.FinalizedCheckPoint
}
// CurrentJustifiedCheckpt mocks CurrentJustifiedCheckpt method in chain service.
func (ms *ChainService) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
return ms.CurrentJustifiedCheckPoint
func (s *ChainService) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
return s.CurrentJustifiedCheckPoint
}
// PreviousJustifiedCheckpt mocks PreviousJustifiedCheckpt method in chain service.
func (ms *ChainService) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
return ms.PreviousJustifiedCheckPoint
func (s *ChainService) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
return s.PreviousJustifiedCheckPoint
}
// ReceiveAttestation mocks ReceiveAttestation method in chain service.
func (ms *ChainService) ReceiveAttestation(_ context.Context, _ *ethpb.Attestation) error {
func (s *ChainService) ReceiveAttestation(_ context.Context, _ *ethpb.Attestation) error {
return nil
}
// ReceiveAttestationNoPubsub mocks ReceiveAttestationNoPubsub method in chain service.
func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attestation) error {
func (s *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attestation) error {
return nil
}
// AttestationPreState mocks AttestationPreState method in chain service.
func (ms *ChainService) AttestationPreState(_ context.Context, _ *ethpb.Attestation) (*stateTrie.BeaconState, error) {
return ms.State, nil
func (s *ChainService) AttestationPreState(_ context.Context, _ *ethpb.Attestation) (iface.BeaconState, error) {
return s.State, nil
}
// HeadValidatorsIndices mocks the same method in the chain service.
func (ms *ChainService) HeadValidatorsIndices(_ context.Context, epoch uint64) ([]uint64, error) {
if ms.State == nil {
return []uint64{}, nil
func (s *ChainService) HeadValidatorsIndices(_ context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error) {
if s.State == nil {
return []types.ValidatorIndex{}, nil
}
return helpers.ActiveValidatorIndices(ms.State, epoch)
return helpers.ActiveValidatorIndices(s.State, epoch)
}
// HeadSeed mocks the same method in the chain service.
func (ms *ChainService) HeadSeed(_ context.Context, epoch uint64) ([32]byte, error) {
return helpers.Seed(ms.State, epoch, params.BeaconConfig().DomainBeaconAttester)
func (s *ChainService) HeadSeed(_ context.Context, epoch types.Epoch) ([32]byte, error) {
return helpers.Seed(s.State, epoch, params.BeaconConfig().DomainBeaconAttester)
}
// HeadETH1Data provides the current ETH1Data of the head state.
func (ms *ChainService) HeadETH1Data() *ethpb.Eth1Data {
return ms.ETH1Data
func (s *ChainService) HeadETH1Data() *ethpb.Eth1Data {
return s.ETH1Data
}
// ProtoArrayStore mocks the same method in the chain service.
func (ms *ChainService) ProtoArrayStore() *protoarray.Store {
return ms.ForkChoiceStore
func (s *ChainService) ProtoArrayStore() *protoarray.Store {
return s.ForkChoiceStore
}
// GenesisTime mocks the same method in the chain service.
func (ms *ChainService) GenesisTime() time.Time {
return ms.Genesis
func (s *ChainService) GenesisTime() time.Time {
return s.Genesis
}
// GenesisValidatorRoot mocks the same method in the chain service.
func (ms *ChainService) GenesisValidatorRoot() [32]byte {
return ms.ValidatorsRoot
func (s *ChainService) GenesisValidatorRoot() [32]byte {
return s.ValidatorsRoot
}
// CurrentSlot mocks the same method in the chain service.
func (ms *ChainService) CurrentSlot() uint64 {
return uint64(time.Now().Unix()-ms.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot
func (s *ChainService) CurrentSlot() types.Slot {
if s.Slot != nil {
return *s.Slot
}
return types.Slot(uint64(time.Now().Unix()-s.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot)
}
// Participation mocks the same method in the chain service.
func (ms *ChainService) Participation(_ uint64) *precompute.Balance {
return ms.Balance
func (s *ChainService) Participation(_ uint64) *precompute.Balance {
return s.Balance
}
// IsValidAttestation always returns true.
func (ms *ChainService) IsValidAttestation(_ context.Context, _ *ethpb.Attestation) bool {
return ms.ValidAttestation
func (s *ChainService) IsValidAttestation(_ context.Context, _ *ethpb.Attestation) bool {
return s.ValidAttestation
}
// IsCanonical returns and determines whether a block with the provided root is part of
// the canonical chain.
func (ms *ChainService) IsCanonical(_ context.Context, r [32]byte) (bool, error) {
if ms.CanonicalRoots != nil {
_, ok := ms.CanonicalRoots[r]
func (s *ChainService) IsCanonical(_ context.Context, r [32]byte) (bool, error) {
if s.CanonicalRoots != nil {
_, ok := s.CanonicalRoots[r]
return ok, nil
}
return true, nil
}
// HasInitSyncBlock mocks the same method in the chain service.
func (ms *ChainService) HasInitSyncBlock(_ [32]byte) bool {
func (s *ChainService) HasInitSyncBlock(_ [32]byte) bool {
return false
}
// HeadGenesisValidatorRoot mocks HeadGenesisValidatorRoot method in chain service.
func (ms *ChainService) HeadGenesisValidatorRoot() [32]byte {
func (s *ChainService) HeadGenesisValidatorRoot() [32]byte {
return [32]byte{}
}
// VerifyBlkDescendant mocks VerifyBlkDescendant and always returns nil.
func (ms *ChainService) VerifyBlkDescendant(_ context.Context, _ [32]byte) error {
return ms.VerifyBlkDescendantErr
func (s *ChainService) VerifyBlkDescendant(_ context.Context, _ [32]byte) error {
return s.VerifyBlkDescendantErr
}
// VerifyLmdFfgConsistency mocks VerifyLmdFfgConsistency and always returns nil.
func (ms *ChainService) VerifyLmdFfgConsistency(_ context.Context, a *ethpb.Attestation) error {
func (s *ChainService) VerifyLmdFfgConsistency(_ context.Context, a *ethpb.Attestation) error {
if !bytes.Equal(a.Data.BeaconBlockRoot, a.Data.Target.Root) {
return errors.New("LMD and FFG miss matched")
}
@@ -370,9 +378,18 @@ func (ms *ChainService) VerifyLmdFfgConsistency(_ context.Context, a *ethpb.Atte
}
// VerifyFinalizedConsistency mocks VerifyFinalizedConsistency and always returns nil.
func (ms *ChainService) VerifyFinalizedConsistency(_ context.Context, r []byte) error {
if !bytes.Equal(r, ms.FinalizedCheckPoint.Root) {
func (s *ChainService) VerifyFinalizedConsistency(_ context.Context, r []byte) error {
if !bytes.Equal(r, s.FinalizedCheckPoint.Root) {
return errors.New("Root and finalized store are not consistent")
}
return nil
}
// ChainHeads mocks ChainHeads and always return nil.
func (s *ChainService) ChainHeads() ([][32]byte, []types.Slot) {
return [][32]byte{
bytesutil.ToBytes32(bytesutil.PadTo([]byte("foo"), 32)),
bytesutil.ToBytes32(bytesutil.PadTo([]byte("bar"), 32)),
},
[]types.Slot{0, 1}
}

View File

@@ -14,7 +14,7 @@ import (
// Reference design: https://github.com/ethereum/eth2.0-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 len(s.wsRoot) == 0 || s.wsEpoch == 0 {
if s.cfg.WeakSubjectivityCheckpt == nil || len(s.cfg.WeakSubjectivityCheckpt.Root) == 0 || s.cfg.WeakSubjectivityCheckpt.Epoch == 0 {
return nil
}
@@ -23,28 +23,28 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
if s.wsVerified {
return nil
}
if s.wsEpoch > s.finalizedCheckpt.Epoch {
if s.cfg.WeakSubjectivityCheckpt.Epoch > s.finalizedCheckpt.Epoch {
return nil
}
r := bytesutil.ToBytes32(s.wsRoot)
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.wsEpoch)
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.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
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.beaconDB.HasBlock(ctx, r) {
if !s.cfg.BeaconDB.HasBlock(ctx, r) {
return fmt.Errorf("node does not have root in DB: %#x", r)
}
startSlot, err := helpers.StartSlot(s.wsEpoch)
startSlot, err := helpers.StartSlot(s.cfg.WeakSubjectivityCheckpt.Epoch)
if err != nil {
return err
}
// 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.beaconDB.BlockRoots(ctx, filter)
roots, err := s.cfg.BeaconDB.BlockRoots(ctx, filter)
if err != nil {
return err
}
@@ -56,5 +56,5 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
}
}
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.wsEpoch)
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
}

View File

@@ -4,26 +4,28 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
db, _ := testDB.SetupDB(t)
beaconDB := testDB.SetupDB(t)
b := testutil.NewBeaconBlock()
b.Block.Slot = 32
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
tests := []struct {
wsVerified bool
wantErr bool
wsRoot [32]byte
wsEpoch uint64
finalizedEpoch uint64
checkpt *ethpb.Checkpoint
finalizedEpoch types.Epoch
errString string
name string
}{
@@ -33,37 +35,34 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
},
{
name: "already verified",
wsEpoch: 2,
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 2,
wsVerified: true,
wantErr: false,
},
{
name: "not yet to verify, ws epoch higher than finalized epoch",
wsEpoch: 2,
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 1,
wantErr: false,
},
{
name: "can't find the block in DB",
wsEpoch: 1,
wsRoot: [32]byte{'a'},
checkpt: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: 1},
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in DB",
},
{
name: "can't find the block corresponds to ws epoch in DB",
wsEpoch: 2,
wsRoot: r, // Root belongs in epoch 1.
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",
},
{
name: "can verify and pass",
wsEpoch: 1,
wsRoot: r,
checkpt: &ethpb.Checkpoint{Root: r[:], Epoch: 1},
finalizedEpoch: 3,
wantErr: false,
},
@@ -71,9 +70,7 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
beaconDB: db,
wsRoot: tt.wsRoot[:],
wsEpoch: tt.wsEpoch,
cfg: &Config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
wsVerified: tt.wsVerified,
finalizedCheckpt: &ethpb.Checkpoint{Epoch: tt.finalizedEpoch},
}

View File

@@ -1,8 +1,7 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
# gazelle:ignore committee_disabled.go
# gazelle:ignore proposer_indices_disabled.go
# gazelle:exclude committee_disabled.go
# gazelle:exclude proposer_indices_disabled.go
go_library(
name = "go_default_library",
srcs = [
@@ -11,15 +10,13 @@ go_library(
"committees.go",
"common.go",
"doc.go",
"hot_state_cache.go",
"skip_slot_cache.go",
"state_summary.go",
"subnet_ids.go",
"proposer_indices_type.go",
"skip_slot_cache.go",
"subnet_ids.go",
] + select({
"//fuzz:fuzzing_enabled": [
"committee_disabled.go",
"proposer_indices_disabled.go"
"proposer_indices_disabled.go",
],
"//conditions:default": [
"committee.go",
@@ -33,9 +30,9 @@ go_library(
"//tools:__subpackages__",
],
deps = [
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/featureconfig:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//shared/copyutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
@@ -43,7 +40,7 @@ go_library(
"@com_github_patrickmn_go_cache//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
@@ -54,26 +51,26 @@ go_test(
size = "small",
srcs = [
"attestation_data_test.go",
"cache_test.go",
"checkpoint_state_test.go",
"committee_fuzz_test.go",
"committee_test.go",
"cache_test.go",
"hot_state_cache_test.go",
"proposer_indices_test.go",
"skip_slot_cache_test.go",
"subnet_ids_test.go",
"proposer_indices_test.go"
],
embed = [":go_default_library"],
deps = [
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -10,8 +10,8 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"k8s.io/client-go/tools/cache"
)
@@ -98,7 +98,7 @@ func (c *AttestationCache) Get(ctx context.Context, req *ethpb.AttestationDataRe
if exists && item != nil && item.(*attestationReqResWrapper).res != nil {
attestationCacheHit.Inc()
return state.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
return copyutil.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
}
attestationCacheMiss.Inc()
return nil, nil

View File

@@ -4,10 +4,10 @@ import (
"context"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"google.golang.org/protobuf/proto"
)
func TestAttestationCache_RoundTrip(t *testing.T) {

View File

@@ -1,17 +1,9 @@
package cache
import (
"os"
"testing"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
)
func TestMain(m *testing.M) {
run := func() int {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{EnableEth1DataVoteCache: true})
defer resetCfg()
return m.Run()
}
os.Exit(run())
m.Run()
}

View File

@@ -6,8 +6,8 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
@@ -47,7 +47,7 @@ func NewCheckpointStateCache() *CheckpointStateCache {
// StateByCheckpoint fetches state by checkpoint. Returns true with a
// reference to the CheckpointState info, if exists. Otherwise returns false, nil.
func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTrie.BeaconState, error) {
func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (iface.BeaconState, error) {
c.lock.RLock()
defer c.lock.RUnlock()
h, err := hashutil.HashProto(cp)
@@ -60,7 +60,7 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
if exists && item != nil {
checkpointStateHit.Inc()
// Copy here is unnecessary since the return will only be used to verify attestation signature.
return item.(*stateTrie.BeaconState), nil
return item.(iface.BeaconState), nil
}
checkpointStateMiss.Inc()
@@ -69,7 +69,7 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
// AddCheckpointState adds CheckpointState object to the cache. This method also trims the least
// recently added CheckpointState object if the cache size has ready the max cache size limit.
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s *stateTrie.BeaconState) error {
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s iface.ReadOnlyBeaconState) error {
c.lock.Lock()
defer c.lock.Unlock()
h, err := hashutil.HashProto(cp)

View File

@@ -3,21 +3,23 @@ package cache
import (
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
types "github.com/prysmaticlabs/eth2-types"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"google.golang.org/protobuf/proto"
)
func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
cache := NewCheckpointStateCache()
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st, err := v1.InitializeFromProto(&pb.BeaconState{
GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:],
Slot: 64,
})
@@ -25,19 +27,23 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
state, err := cache.StateByCheckpoint(cp1)
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Expected state not to exist in empty cache")
assert.Equal(t, iface.BeaconState(nil), state, "Expected state not to exist in empty cache")
require.NoError(t, cache.AddCheckpointState(cp1, st))
state, err = cache.StateByCheckpoint(cp1)
require.NoError(t, err)
if !proto.Equal(state.InnerStateUnsafe(), st.InnerStateUnsafe()) {
pbState1, err := v1.ProtobufBeaconState(state.InnerStateUnsafe())
require.NoError(t, err)
pbState2, err := v1.ProtobufBeaconState(st.InnerStateUnsafe())
require.NoError(t, err)
if !proto.Equal(pbState1, pbState2) {
t.Error("incorrectly cached state")
}
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
st2, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st2, err := v1.InitializeFromProto(&pb.BeaconState{
Slot: 128,
})
require.NoError(t, err)
@@ -54,14 +60,14 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
func TestCheckpointStateCache_MaxSize(t *testing.T) {
c := NewCheckpointStateCache()
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st, err := v1.InitializeFromProto(&pb.BeaconState{
Slot: 0,
})
require.NoError(t, err)
for i := uint64(0); i < uint64(maxCheckpointStateSize+100); i++ {
require.NoError(t, st.SetSlot(i))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: i, Root: make([]byte, 32)}, st))
require.NoError(t, st.SetSlot(types.Slot(i)))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: types.Epoch(i), Root: make([]byte, 32)}, st))
}
assert.Equal(t, maxCheckpointStateSize, len(c.cache.Keys()))

View File

@@ -6,11 +6,12 @@ import (
"errors"
"sync"
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"k8s.io/client-go/tools/cache"
)
var (
@@ -32,7 +33,7 @@ var (
// CommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type CommitteeCache struct {
CommitteeCache *cache.FIFO
CommitteeCache *lru.Cache
lock sync.RWMutex
}
@@ -42,28 +43,29 @@ func committeeKeyFn(obj interface{}) (string, error) {
if !ok {
return "", ErrNotCommittee
}
return key(info.Seed), nil
}
// NewCommitteesCache creates a new committee cache for storing/accessing shuffled indices of a committee.
func NewCommitteesCache() *CommitteeCache {
cCache, err := lru.New(int(maxCommitteesCacheSize))
// An error is only returned if the size of the cache is
// <= 0.
if err != nil {
panic(err)
}
return &CommitteeCache{
CommitteeCache: cache.NewFIFO(committeeKeyFn),
CommitteeCache: cCache,
}
}
// Committee fetches the shuffled indices by slot and committee index. Every list of indices
// represent one committee. Returns true if the list exists with slot and committee index. Otherwise returns false, nil.
func (c *CommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]uint64, error) {
func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.CommitteeIndex) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return nil, err
}
obj, exists := c.CommitteeCache.Get(key(seed))
if exists {
CommitteeCacheHit.Inc()
} else {
@@ -77,11 +79,11 @@ func (c *CommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]
}
committeeCountPerSlot := uint64(1)
if item.CommitteeCount/params.BeaconConfig().SlotsPerEpoch > 1 {
committeeCountPerSlot = item.CommitteeCount / params.BeaconConfig().SlotsPerEpoch
if item.CommitteeCount/uint64(params.BeaconConfig().SlotsPerEpoch) > 1 {
committeeCountPerSlot = item.CommitteeCount / uint64(params.BeaconConfig().SlotsPerEpoch)
}
indexOffSet := index + (slot%params.BeaconConfig().SlotsPerEpoch)*committeeCountPerSlot
indexOffSet := uint64(index) + uint64(slot.ModSlot(params.BeaconConfig().SlotsPerEpoch).Mul(committeeCountPerSlot))
start, end := startEndIndices(item, indexOffSet)
if end > uint64(len(item.ShuffledIndices)) || end < start {
@@ -96,22 +98,19 @@ func (c *CommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]
func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.CommitteeCache.AddIfNotPresent(committees); err != nil {
key, err := committeeKeyFn(committees)
if err != nil {
return err
}
trim(c.CommitteeCache, maxCommitteesCacheSize)
_ = c.CommitteeCache.Add(key, committees)
return nil
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return nil, err
}
obj, exists := c.CommitteeCache.Get(key(seed))
if exists {
CommitteeCacheHit.Inc()
@@ -132,11 +131,7 @@ func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return 0, err
}
obj, exists := c.CommitteeCache.Get(key(seed))
if exists {
CommitteeCacheHit.Inc()
} else {
@@ -154,8 +149,8 @@ func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
// HasEntry returns true if the committee cache has a value.
func (c *CommitteeCache) HasEntry(seed string) bool {
_, ok, err := c.CommitteeCache.GetByKey(seed)
return err == nil && ok
_, ok := c.CommitteeCache.Get(seed)
return ok
}
func startEndIndices(c *Committees, index uint64) (uint64, uint64) {

View File

@@ -3,6 +3,8 @@
// This file is used in fuzzer builds to bypass global committee caches.
package cache
import types "github.com/prysmaticlabs/eth2-types"
// FakeCommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type FakeCommitteeCache struct {
}
@@ -14,7 +16,7 @@ func NewCommitteesCache() *FakeCommitteeCache {
// Committee fetches the shuffled indices by slot and committee index. Every list of indices
// represent one committee. Returns true if the list exists with slot and committee index. Otherwise returns false, nil.
func (c *FakeCommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]uint64, error) {
func (c *FakeCommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.CommitteeIndex) ([]types.ValidatorIndex, error) {
return nil, nil
}
@@ -25,12 +27,12 @@ func (c *FakeCommitteeCache) AddCommitteeShuffledList(committees *Committees) er
}
// AddProposerIndicesList updates the committee shuffled list with proposer indices.
func (c *FakeCommitteeCache) AddProposerIndicesList(seed [32]byte, indices []uint64) error {
func (c *FakeCommitteeCache) AddProposerIndicesList(seed [32]byte, indices []types.ValidatorIndex) error {
return nil
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *FakeCommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
func (c *FakeCommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}
@@ -40,7 +42,7 @@ func (c *FakeCommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
}
// ProposerIndices returns the proposer indices of a given seed.
func (c *FakeCommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
func (c *FakeCommitteeCache) ProposerIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}

View File

@@ -32,7 +32,7 @@ func TestCommitteeCache_FuzzCommitteesByEpoch(t *testing.T) {
require.NoError(t, err)
}
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
}
func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
@@ -49,5 +49,5 @@ func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
assert.DeepEqual(t, c.SortedIndices, indices)
}
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
}

View File

@@ -6,6 +6,7 @@ import (
"strconv"
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -16,7 +17,7 @@ func TestCommitteeKeyFn_OK(t *testing.T) {
item := &Committees{
CommitteeCount: 1,
Seed: [32]byte{'A'},
ShuffledIndices: []uint64{1, 2, 3, 4, 5},
ShuffledIndices: []types.ValidatorIndex{1, 2, 3, 4, 5},
}
k, err := committeeKeyFn(item)
@@ -33,13 +34,13 @@ func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{
ShuffledIndices: []uint64{1, 2, 3, 4, 5, 6},
ShuffledIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6},
Seed: [32]byte{'A'},
CommitteeCount: 3,
}
slot := params.BeaconConfig().SlotsPerEpoch
committeeIndex := uint64(1)
committeeIndex := types.CommitteeIndex(1)
indices, err := cache.Committee(slot, item.Seed, committeeIndex)
require.NoError(t, err)
if indices != nil {
@@ -47,18 +48,18 @@ func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
wantedIndex := uint64(0)
wantedIndex := types.CommitteeIndex(0)
indices, err = cache.Committee(slot, item.Seed, wantedIndex)
require.NoError(t, err)
start, end := startEndIndices(item, wantedIndex)
start, end := startEndIndices(item, uint64(wantedIndex))
assert.DeepEqual(t, item.ShuffledIndices[start:end], indices)
}
func TestCommitteeCache_ActiveIndices(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
indices, err := cache.ActiveIndices(item.Seed)
require.NoError(t, err)
if indices != nil {
@@ -75,7 +76,7 @@ func TestCommitteeCache_ActiveIndices(t *testing.T) {
func TestCommitteeCache_ActiveCount(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
count, err := cache.ActiveIndicesCount(item.Seed)
require.NoError(t, err)
assert.Equal(t, 0, count, "Expected active count not to exist in empty cache")
@@ -99,11 +100,11 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
require.NoError(t, cache.AddCommitteeShuffledList(item))
}
k := cache.CommitteeCache.ListKeys()
k := cache.CommitteeCache.Keys()
assert.Equal(t, maxCommitteesCacheSize, uint64(len(k)))
sort.Slice(k, func(i, j int) bool {
return k[i] < k[j]
return k[i].(string) < k[j].(string)
})
wanted := end - int(maxCommitteesCacheSize)
s := bytesutil.ToBytes32([]byte(strconv.Itoa(wanted)))
@@ -116,13 +117,15 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
func TestCommitteeCacheOutOfRange(t *testing.T) {
cache := NewCommitteesCache()
seed := bytesutil.ToBytes32([]byte("foo"))
err := cache.CommitteeCache.Add(&Committees{
comms := &Committees{
CommitteeCount: 1,
Seed: seed,
ShuffledIndices: []uint64{0},
SortedIndices: []uint64{},
})
require.NoError(t, err)
ShuffledIndices: []types.ValidatorIndex{0},
SortedIndices: []types.ValidatorIndex{},
}
key, err := committeeKeyFn(comms)
assert.NoError(t, err)
_ = cache.CommitteeCache.Add(key, comms)
_, err = cache.Committee(0, seed, math.MaxUint64) // Overflow!
require.NotNil(t, err, "Did not fail as expected")

View File

@@ -1,6 +1,10 @@
package cache
import "errors"
import (
"errors"
types "github.com/prysmaticlabs/eth2-types"
)
// ErrNotCommittee will be returned when a cache object is not a pointer to
// a Committee struct.
@@ -10,6 +14,6 @@ var ErrNotCommittee = errors.New("object is not a committee struct")
type Committees struct {
CommitteeCount uint64
Seed [32]byte
ShuffledIndices []uint64
SortedIndices []uint64
ShuffledIndices []types.ValidatorIndex
SortedIndices []types.ValidatorIndex
}

View File

@@ -8,7 +8,7 @@ import (
var (
// maxCacheSize is 4x of the epoch length for additional cache padding.
// Requests should be only accessing committees within defined epoch length.
maxCacheSize = 4 * params.BeaconConfig().SlotsPerEpoch
maxCacheSize = uint64(4 * params.BeaconConfig().SlotsPerEpoch)
)
// trim the FIFO queue to the maxSize.

View File

@@ -1,23 +1,24 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"deposits_cache.go",
"log.go",
"pending_deposits.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//proto/beacon/db:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/trieutil: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",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
@@ -32,13 +33,13 @@ go_test(
embed = [":go_default_library"],
deps = [
"//proto/beacon/db:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -12,14 +12,15 @@ import (
"sort"
"sync"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/trieutil"
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -74,25 +75,32 @@ func New() (*DepositCache, error) {
// InsertDeposit into the database. If deposit or block number are nil
// then this method does nothing.
func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) {
func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "DepositsCache.InsertDeposit")
defer span.End()
if d == nil {
log.WithFields(log.Fields{
log.WithFields(logrus.Fields{
"block": blockNum,
"deposit": d,
"index": index,
"deposit root": hex.EncodeToString(depositRoot[:]),
}).Warn("Ignoring nil deposit insertion")
return
return errors.New("nil deposit inserted into the cache")
}
dc.depositsLock.Lock()
defer dc.depositsLock.Unlock()
if int(index) != len(dc.deposits) {
return errors.Errorf("wanted deposit with index %d to be inserted but received %d", len(dc.deposits), index)
}
// Keep the slice sorted on insertion in order to avoid costly sorting on retrieval.
heightIdx := sort.Search(len(dc.deposits), func(i int) bool { return dc.deposits[i].Index >= index })
newDeposits := append([]*dbpb.DepositContainer{{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}}, dc.deposits[heightIdx:]...)
newDeposits := append(
[]*dbpb.DepositContainer{{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}},
dc.deposits[heightIdx:]...)
dc.deposits = append(dc.deposits[:heightIdx], newDeposits...)
historicalDepositsCount.Inc()
return nil
}
// InsertDepositContainers inserts a set of deposit containers into our deposit cache.
@@ -165,7 +173,7 @@ func (dc *DepositCache) AllDeposits(ctx context.Context, untilBlk *big.Int) []*e
return deposits
}
// DepositsNumberAndRootAtHeight returns number of deposits made prior to blockheight and the
// DepositsNumberAndRootAtHeight returns number of deposits made up to blockheight and the
// root that corresponds to the latest deposit at that blockheight.
func (dc *DepositCache) DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte) {
ctx, span := trace.StartSpan(ctx, "DepositsCache.DepositsNumberAndRootAtHeight")

View File

@@ -7,8 +7,8 @@ import (
"math/big"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -26,7 +26,7 @@ func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{})
assert.ErrorContains(t, "nil deposit inserted into the cache", dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{}))
require.Equal(t, 0, len(dc.deposits), "Number of deposits changed")
assert.Equal(t, nilDepositErr, hook.LastEntry().Message)
@@ -37,37 +37,52 @@ func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
require.NoError(t, err)
insertions := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
blkNum uint64
deposit *ethpb.Deposit
index int64
expectedErr string
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 0,
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 0,
expectedErr: "",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 3,
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 3,
expectedErr: "wanted deposit with index 1 to be inserted but received 3",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 1,
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 1,
expectedErr: "",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 4,
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 4,
expectedErr: "wanted deposit with index 2 to be inserted but received 4",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 2,
expectedErr: "",
},
}
for _, ins := range insertions {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
if ins.expectedErr != "" {
assert.ErrorContains(t, ins.expectedErr, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
} else {
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
}
}
expectedIndices := []int64{0, 1, 3, 4}
expectedIndices := []int64{0, 1, 2}
for i, ei := range expectedIndices {
assert.Equal(t, ei, dc.deposits[i].Index,
fmt.Sprintf("dc.deposits[%d].Index = %d, wanted %d", i, dc.deposits[i].Index, ei))
@@ -154,121 +169,148 @@ func TestAllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
assert.Equal(t, 5, len(d))
}
func TestDepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing.T) {
dc, err := New()
require.NoError(t, err)
func TestDepositsNumberAndRootAtHeight(t *testing.T) {
wantedRoot := bytesutil.PadTo([]byte("root"), 32)
t.Run("requesting_last_item_works", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Index: 0,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Index: 1,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Index: 2,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 13,
Index: 3,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(13))
assert.Equal(t, 4, int(n))
require.DeepEqual(t, wantedRoot, root[:])
})
t.Run("only_one_item", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Index: 0,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
}
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
assert.Equal(t, 1, int(n))
require.DeepEqual(t, wantedRoot, root[:])
})
t.Run("none_at_height_some_below", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(11))
assert.Equal(t, 5, int(n))
assert.Equal(t, bytesutil.ToBytes32([]byte("root")), root)
}
func TestDepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOldestDeposit(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 8,
Index: 0,
Deposit: &ethpb.Deposit{},
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
{
Eth1BlockHeight: 9,
Index: 1,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
}
{
Eth1BlockHeight: 11,
Index: 2,
Deposit: &ethpb.Deposit{},
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
assert.Equal(t, 2, int(n))
require.DeepEqual(t, wantedRoot, root[:])
})
t.Run("none_at_height_none_below", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(2))
assert.Equal(t, 0, int(n))
assert.Equal(t, [32]byte{}, root)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 8,
Index: 0,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(7))
assert.Equal(t, 0, int(n))
require.DeepEqual(t, params.BeaconConfig().ZeroHash, root)
})
t.Run("none_at_height_one_below", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 8,
Index: 0,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
assert.Equal(t, 1, int(n))
require.DeepEqual(t, wantedRoot, root[:])
})
t.Run("some_greater_some_lower", func(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 8,
Index: 0,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 8,
Index: 1,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 9,
Index: 2,
Deposit: &ethpb.Deposit{},
DepositRoot: wantedRoot,
},
{
Eth1BlockHeight: 10,
Index: 3,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Index: 4,
Deposit: &ethpb.Deposit{},
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(9))
assert.Equal(t, 3, int(n))
require.DeepEqual(t, wantedRoot, root[:])
})
}
func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
@@ -606,13 +648,13 @@ func TestPruneProofs_Ok(t *testing.T) {
}
for _, ins := range deposits {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
}
require.NoError(t, dc.PruneProofs(context.Background(), 1))
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[1].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[1].Deposit.Proof)
assert.NotNil(t, dc.deposits[2].Deposit.Proof)
assert.NotNil(t, dc.deposits[3].Deposit.Proof)
}
@@ -649,12 +691,12 @@ func TestPruneProofs_SomeAlreadyPruned(t *testing.T) {
}
for _, ins := range deposits {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
}
require.NoError(t, dc.PruneProofs(context.Background(), 2))
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[2].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[2].Deposit.Proof)
}
func TestPruneProofs_PruneAllWhenDepositIndexTooBig(t *testing.T) {
@@ -689,15 +731,15 @@ func TestPruneProofs_PruneAllWhenDepositIndexTooBig(t *testing.T) {
}
for _, ins := range deposits {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
}
require.NoError(t, dc.PruneProofs(context.Background(), 99))
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[1].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[2].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[3].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[1].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[2].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[3].Deposit.Proof)
}
func TestPruneProofs_CorrectlyHandleLastIndex(t *testing.T) {
@@ -732,15 +774,15 @@ func TestPruneProofs_CorrectlyHandleLastIndex(t *testing.T) {
}
for _, ins := range deposits {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
}
require.NoError(t, dc.PruneProofs(context.Background(), 4))
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[1].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[2].Deposit.Proof)
assert.DeepEqual(t, ([][]byte)(nil), dc.deposits[3].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[0].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[1].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[2].Deposit.Proof)
assert.DeepEqual(t, [][]byte(nil), dc.deposits[3].Deposit.Proof)
}
func makeDepositProof() [][]byte {

View File

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

View File

@@ -7,10 +7,10 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -33,7 +33,7 @@ func (dc *DepositCache) InsertPendingDeposit(ctx context.Context, d *ethpb.Depos
ctx, span := trace.StartSpan(ctx, "DepositsCache.InsertPendingDeposit")
defer span.End()
if d == nil {
log.WithFields(log.Fields{
log.WithFields(logrus.Fields{
"block": blockNum,
"deposit": d,
}).Debug("Ignoring nil deposit insertion")

View File

@@ -5,11 +5,11 @@ import (
"math/big"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"google.golang.org/protobuf/proto"
)
var _ PendingDepositsFetcher = (*DepositCache)(nil)
@@ -90,7 +90,7 @@ func TestPendingDeposits_OK(t *testing.T) {
{Proof: [][]byte{[]byte("A")}},
{Proof: [][]byte{[]byte("B")}},
}
assert.DeepEqual(t, expected, deposits)
assert.DeepSSZEqual(t, expected, deposits)
all := dc.PendingDeposits(context.Background(), nil)
assert.Equal(t, len(dc.pendingDeposits), len(all), "PendingDeposits(ctx, nil) did not return all deposits")

View File

@@ -1,5 +1,5 @@
// Package cache includes all important caches for the runtime
// of an eth2 beacon node, ensuring the node does not spend
// of an Ethereum Beacon Node, ensuring the node does not spend
// resources computing duplicate operations such as committee
// calculations for validators during the same epoch, etc.
package cache

View File

@@ -1,34 +0,0 @@
package cache_test
import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestHotStateCache_RoundTrip(t *testing.T) {
c := cache.NewHotStateCache()
root := [32]byte{'A'}
state := c.Get(root)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state)
assert.Equal(t, false, c.Has(root), "Empty cache has an object")
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
require.NoError(t, err)
c.Put(root, state)
assert.Equal(t, true, c.Has(root), "Empty cache does not have an object")
res := c.Get(root)
assert.NotNil(t, state)
assert.DeepEqual(t, res.CloneInnerState(), state.CloneInnerState(), "Expected equal protos to return from cache")
c.Delete(root)
assert.Equal(t, false, c.Has(root), "Cache not supposed to have the object")
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
types "github.com/prysmaticlabs/eth2-types"
"k8s.io/client-go/tools/cache"
)
@@ -63,8 +64,19 @@ func (c *ProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error {
return nil
}
// HasProposerIndices returns the proposer indices of a block root seed.
func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
c.lock.RLock()
defer c.lock.RUnlock()
_, exists, err := c.ProposerIndicesCache.GetByKey(key(r))
if err != nil {
return false, err
}
return exists, nil
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.ProposerIndicesCache.GetByKey(key(r))

View File

@@ -3,6 +3,8 @@
// This file is used in fuzzer builds to bypass proposer indices caches.
package cache
import types "github.com/prysmaticlabs/eth2-types"
// FakeProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
type FakeProposerIndicesCache struct {
}
@@ -19,6 +21,11 @@ func (c *FakeProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}
// HasProposerIndices returns the proposer indices of a block root seed.
func (c *FakeProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
return false, nil
}

View File

@@ -4,6 +4,7 @@ import (
"strconv"
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -12,7 +13,7 @@ import (
func TestProposerKeyFn_OK(t *testing.T) {
item := &ProposerIndices{
BlockRoot: [32]byte{'A'},
ProposerIndices: []uint64{1, 2, 3, 4, 5},
ProposerIndices: []types.ValidatorIndex{1, 2, 3, 4, 5},
}
k, err := proposerIndicesKeyFn(item)
@@ -33,6 +34,9 @@ func TestProposerCache_AddProposerIndicesList(t *testing.T) {
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
has, err := cache.HasProposerIndices(bRoot)
require.NoError(t, err)
assert.Equal(t, false, has)
require.NoError(t, cache.AddProposerIndices(&ProposerIndices{
ProposerIndices: indices,
BlockRoot: bRoot,
@@ -41,13 +45,20 @@ func TestProposerCache_AddProposerIndicesList(t *testing.T) {
received, err := cache.ProposerIndices(bRoot)
require.NoError(t, err)
assert.DeepEqual(t, received, indices)
has, err = cache.HasProposerIndices(bRoot)
require.NoError(t, err)
assert.Equal(t, true, has)
item := &ProposerIndices{BlockRoot: [32]byte{'B'}, ProposerIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &ProposerIndices{BlockRoot: [32]byte{'B'}, ProposerIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
require.NoError(t, cache.AddProposerIndices(item))
received, err = cache.ProposerIndices(item.BlockRoot)
require.NoError(t, err)
assert.DeepEqual(t, item.ProposerIndices, received)
has, err = cache.HasProposerIndices(bRoot)
require.NoError(t, err)
assert.Equal(t, true, has)
}
func TestProposerCache_CanRotate(t *testing.T) {

View File

@@ -1,6 +1,10 @@
package cache
import "errors"
import (
"errors"
types "github.com/prysmaticlabs/eth2-types"
)
// ErrNotProposerIndices will be returned when a cache object is not a pointer to
// a ProposerIndices struct.
@@ -9,5 +13,5 @@ var ErrNotProposerIndices = errors.New("object is not a proposer indices struct"
// ProposerIndices defines the cached struct for proposer indices.
type ProposerIndices struct {
BlockRoot [32]byte
ProposerIndices []uint64
ProposerIndices []types.ValidatorIndex
}

View File

@@ -9,7 +9,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"go.opencensus.io/trace"
)
@@ -57,7 +57,7 @@ func (c *SkipSlotCache) Disable() {
// Get waits for any in progress calculation to complete before returning a
// cached response, if any.
func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (*stateTrie.BeaconState, error) {
func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "skipSlotCache.Get")
defer span.End()
if c.disabled {
@@ -97,7 +97,7 @@ func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (*stateTrie.BeaconS
if exists && item != nil {
skipSlotCacheHit.Inc()
span.AddAttributes(trace.BoolAttribute("hit", true))
return item.(*stateTrie.BeaconState).Copy(), nil
return item.(iface.BeaconState).Copy(), nil
}
skipSlotCacheMiss.Inc()
span.AddAttributes(trace.BoolAttribute("hit", false))
@@ -136,7 +136,7 @@ func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) error {
}
// Put the response in the cache.
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state *stateTrie.BeaconState) error {
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state iface.BeaconState) error {
if c.disabled {
return nil
}

View File

@@ -5,7 +5,8 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -18,11 +19,11 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
r := [32]byte{'a'}
state, err := c.Get(ctx, r)
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Empty cache returned an object")
assert.Equal(t, iface.BeaconState(nil), state, "Empty cache returned an object")
require.NoError(t, c.MarkInProgress(r))
state, err = stateTrie.InitializeFromProto(&pb.BeaconState{
state, err = v1.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
require.NoError(t, err)

View File

@@ -1,65 +0,0 @@
package cache
import (
"sync"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
)
// StateSummaryCache caches state summary object.
type StateSummaryCache struct {
initSyncStateSummaries map[[32]byte]*pb.StateSummary
initSyncStateSummariesLock sync.RWMutex
}
// NewStateSummaryCache creates a new state summary cache.
func NewStateSummaryCache() *StateSummaryCache {
return &StateSummaryCache{
initSyncStateSummaries: make(map[[32]byte]*pb.StateSummary),
}
}
// Put saves a state summary to the initial sync state summaries cache.
func (s *StateSummaryCache) Put(r [32]byte, b *pb.StateSummary) {
s.initSyncStateSummariesLock.Lock()
defer s.initSyncStateSummariesLock.Unlock()
s.initSyncStateSummaries[r] = b
}
// Has checks if a state summary exists in the initial sync state summaries cache using the root
// of the block.
func (s *StateSummaryCache) Has(r [32]byte) bool {
s.initSyncStateSummariesLock.RLock()
defer s.initSyncStateSummariesLock.RUnlock()
_, ok := s.initSyncStateSummaries[r]
return ok
}
// Get retrieves a state summary from the initial sync state summaries cache using the root of
// the block.
func (s *StateSummaryCache) Get(r [32]byte) *pb.StateSummary {
s.initSyncStateSummariesLock.RLock()
defer s.initSyncStateSummariesLock.RUnlock()
b := s.initSyncStateSummaries[r]
return b
}
// GetAll retrieves all the beacon state summaries from the initial sync state summaries cache, the returned
// state summaries are unordered.
func (s *StateSummaryCache) GetAll() []*pb.StateSummary {
s.initSyncStateSummariesLock.RLock()
defer s.initSyncStateSummariesLock.RUnlock()
summaries := make([]*pb.StateSummary, 0, len(s.initSyncStateSummaries))
for _, b := range s.initSyncStateSummaries {
summaries = append(summaries, b)
}
return summaries
}
// Clear clears out the initial sync state summaries cache.
func (s *StateSummaryCache) Clear() {
s.initSyncStateSummariesLock.Lock()
defer s.initSyncStateSummariesLock.Unlock()
s.initSyncStateSummaries = make(map[[32]byte]*pb.StateSummary)
}

View File

@@ -6,6 +6,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/patrickmn/go-cache"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
@@ -25,7 +26,7 @@ var SubnetIDs = newSubnetIDs()
func newSubnetIDs() *subnetIDs {
// Given a node can calculate committee assignments of current epoch and next epoch.
// Max size is set to 2 epoch length.
cacheSize := int(params.BeaconConfig().MaxCommitteesPerSlot * params.BeaconConfig().SlotsPerEpoch * 2)
cacheSize := int(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxCommitteesPerSlot * 2))
attesterCache, err := lru.New(cacheSize)
if err != nil {
panic(err)
@@ -34,31 +35,31 @@ func newSubnetIDs() *subnetIDs {
if err != nil {
panic(err)
}
epochDuration := time.Duration(params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot)
subLength := epochDuration * time.Duration(params.BeaconNetworkConfig().EpochsPerRandomSubnetSubscription)
epochDuration := time.Duration(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
subLength := epochDuration * time.Duration(params.BeaconConfig().EpochsPerRandomSubnetSubscription)
persistentCache := cache.New(subLength*time.Second, epochDuration*time.Second)
return &subnetIDs{attester: attesterCache, aggregator: aggregatorCache, persistentSubnets: persistentCache}
}
// AddAttesterSubnetID adds the subnet index for subscribing subnet for the attester of a given slot.
func (c *subnetIDs) AddAttesterSubnetID(slot, subnetID uint64) {
c.attesterLock.Lock()
defer c.attesterLock.Unlock()
func (s *subnetIDs) AddAttesterSubnetID(slot types.Slot, subnetID uint64) {
s.attesterLock.Lock()
defer s.attesterLock.Unlock()
ids := []uint64{subnetID}
val, exists := c.attester.Get(slot)
val, exists := s.attester.Get(slot)
if exists {
ids = sliceutil.UnionUint64(append(val.([]uint64), ids...))
}
c.attester.Add(slot, ids)
s.attester.Add(slot, ids)
}
// GetAttesterSubnetIDs gets the subnet IDs for subscribed subnets for attesters of the slot.
func (c *subnetIDs) GetAttesterSubnetIDs(slot uint64) []uint64 {
c.attesterLock.RLock()
defer c.attesterLock.RUnlock()
func (s *subnetIDs) GetAttesterSubnetIDs(slot types.Slot) []uint64 {
s.attesterLock.RLock()
defer s.attesterLock.RUnlock()
val, exists := c.attester.Get(slot)
val, exists := s.attester.Get(slot)
if !exists {
return nil
}
@@ -69,24 +70,24 @@ func (c *subnetIDs) GetAttesterSubnetIDs(slot uint64) []uint64 {
}
// AddAggregatorSubnetID adds the subnet ID for subscribing subnet for the aggregator of a given slot.
func (c *subnetIDs) AddAggregatorSubnetID(slot, subnetID uint64) {
c.aggregatorLock.Lock()
defer c.aggregatorLock.Unlock()
func (s *subnetIDs) AddAggregatorSubnetID(slot types.Slot, subnetID uint64) {
s.aggregatorLock.Lock()
defer s.aggregatorLock.Unlock()
ids := []uint64{subnetID}
val, exists := c.aggregator.Get(slot)
val, exists := s.aggregator.Get(slot)
if exists {
ids = sliceutil.UnionUint64(append(val.([]uint64), ids...))
}
c.aggregator.Add(slot, ids)
s.aggregator.Add(slot, ids)
}
// GetAggregatorSubnetIDs gets the subnet IDs for subscribing subnet for aggregator of the slot.
func (c *subnetIDs) GetAggregatorSubnetIDs(slot uint64) []uint64 {
c.aggregatorLock.RLock()
defer c.aggregatorLock.RUnlock()
func (s *subnetIDs) GetAggregatorSubnetIDs(slot types.Slot) []uint64 {
s.aggregatorLock.RLock()
defer s.aggregatorLock.RUnlock()
val, exists := c.aggregator.Get(slot)
val, exists := s.aggregator.Get(slot)
if !exists {
return []uint64{}
}
@@ -95,11 +96,11 @@ func (c *subnetIDs) GetAggregatorSubnetIDs(slot uint64) []uint64 {
// GetPersistentSubnets retrieves the persistent subnet and expiration time of that validator's
// subscription.
func (c *subnetIDs) GetPersistentSubnets(pubkey []byte) ([]uint64, bool, time.Time) {
c.subnetsLock.RLock()
defer c.subnetsLock.RUnlock()
func (s *subnetIDs) GetPersistentSubnets(pubkey []byte) ([]uint64, bool, time.Time) {
s.subnetsLock.RLock()
defer s.subnetsLock.RUnlock()
id, duration, ok := c.persistentSubnets.GetWithExpiration(string(pubkey))
id, duration, ok := s.persistentSubnets.GetWithExpiration(string(pubkey))
if !ok {
return []uint64{}, ok, time.Time{}
}
@@ -108,11 +109,11 @@ func (c *subnetIDs) GetPersistentSubnets(pubkey []byte) ([]uint64, bool, time.Ti
// GetAllSubnets retrieves all the non-expired subscribed subnets of all the validators
// in the cache.
func (c *subnetIDs) GetAllSubnets() []uint64 {
c.subnetsLock.RLock()
defer c.subnetsLock.RUnlock()
func (s *subnetIDs) GetAllSubnets() []uint64 {
s.subnetsLock.RLock()
defer s.subnetsLock.RUnlock()
itemsMap := c.persistentSubnets.Items()
itemsMap := s.persistentSubnets.Items()
var committees []uint64
for _, v := range itemsMap {
@@ -126,9 +127,28 @@ func (c *subnetIDs) GetAllSubnets() []uint64 {
// AddPersistentCommittee adds the relevant committee for that particular validator along with its
// expiration period.
func (c *subnetIDs) AddPersistentCommittee(pubkey []byte, comIndex []uint64, duration time.Duration) {
c.subnetsLock.Lock()
defer c.subnetsLock.Unlock()
func (s *subnetIDs) AddPersistentCommittee(pubkey []byte, comIndex []uint64, duration time.Duration) {
s.subnetsLock.Lock()
defer s.subnetsLock.Unlock()
c.persistentSubnets.Set(string(pubkey), comIndex, duration)
s.persistentSubnets.Set(string(pubkey), comIndex, duration)
}
// EmptyAllCaches empties out all the related caches and flushes any stored
// entries on them. This should only ever be used for testing, in normal
// production, handling of the relevant subnets for each role is done
// separately.
func (s *subnetIDs) EmptyAllCaches() {
// Clear the caches.
s.attesterLock.Lock()
s.attester.Purge()
s.attesterLock.Unlock()
s.aggregatorLock.Lock()
s.aggregator.Purge()
s.aggregatorLock.Unlock()
s.subnetsLock.Lock()
s.persistentSubnets.Flush()
s.subnetsLock.Unlock()
}

View File

@@ -3,13 +3,14 @@ package cache
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestSubnetIDsCache_RoundTrip(t *testing.T) {
c := newSubnetIDs()
slot := uint64(100)
slot := types.Slot(100)
committeeIDs := c.GetAggregatorSubnetIDs(slot)
assert.Equal(t, 0, len(committeeIDs), "Empty cache returned an object")

View File

@@ -1,5 +1,4 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
@@ -21,28 +20,32 @@ go_library(
"//beacon-chain:__subpackages__",
"//fuzz:__pkg__",
"//shared/testutil:__pkg__",
"//spectest:__subpackages__",
"//validator/accounts:__pkg__",
],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/interfaces:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/copyutil:go_default_library",
"//shared/depositutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"//shared/slashutil:go_default_library",
"//shared/sliceutil:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)
@@ -69,22 +72,28 @@ go_test(
shard_count = 2,
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/p2p/types:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//proto/eth/v1alpha1:go_default_library",
"//proto/eth/v1alpha1/wrapper:go_default_library",
"//shared/aggregation:go_default_library",
"//shared/aggregation/attestations:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/copyutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -1,18 +1,18 @@
package blocks
import (
"bytes"
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -21,15 +21,15 @@ import (
// records.
func ProcessAttestations(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
beaconState iface.BeaconState,
b interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
var err error
for idx, attestation := range b.Block.Body.Attestations {
for idx, attestation := range b.Block().Body().Attestations() {
beaconState, err = ProcessAttestation(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
@@ -65,13 +65,13 @@ func ProcessAttestations(
// assert data.source == state.previous_justified_checkpoint
// state.previous_epoch_attestations.append(pending_attestation)
//
// # Check signature
// # Verify signature
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
func ProcessAttestation(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
beaconState, err := ProcessAttestationNoVerifySignature(ctx, beaconState, att)
if err != nil {
return nil, err
@@ -83,15 +83,15 @@ func ProcessAttestation(
// records. The only difference would be that the attestation signature would not be verified.
func ProcessAttestationsNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
beaconState iface.BeaconState,
b interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
body := b.Block().Body()
var err error
for idx, attestation := range body.Attestations {
for idx, attestation := range body.Attestations() {
beaconState, err = ProcessAttestationNoVerifySignature(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
@@ -100,45 +100,50 @@ func ProcessAttestationsNoVerifySignature(
return beaconState, nil
}
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerifySignature(
// VerifyAttestationNoVerifySignature verifies the attestation without verifying the attestation signature. This is
// used before processing attestation with the beacon state.
func VerifyAttestationNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.ReadOnlyBeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationNoVerifySignature")
defer span.End()
if att == nil || att.Data == nil || att.Data.Target == nil {
return nil, errors.New("nil attestation data target")
}
currEpoch := helpers.SlotToEpoch(beaconState.Slot())
var prevEpoch uint64
if currEpoch == 0 {
prevEpoch = 0
} else {
prevEpoch = currEpoch - 1
if err := helpers.ValidateNilAttestation(att); err != nil {
return err
}
currEpoch := helpers.CurrentEpoch(beaconState)
prevEpoch := helpers.PrevEpoch(beaconState)
data := att.Data
if data.Target.Epoch != prevEpoch && data.Target.Epoch != currEpoch {
return nil, fmt.Errorf(
return fmt.Errorf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
data.Target.Epoch,
prevEpoch,
currEpoch,
)
}
if helpers.SlotToEpoch(data.Slot) != data.Target.Epoch {
return nil, fmt.Errorf("data slot is not in the same epoch as target %d != %d", helpers.SlotToEpoch(data.Slot), data.Target.Epoch)
if data.Target.Epoch == currEpoch {
if !beaconState.MatchCurrentJustifiedCheckpoint(data.Source) {
return errors.New("source check point not equal to current justified checkpoint")
}
} else {
if !beaconState.MatchPreviousJustifiedCheckpoint(data.Source) {
return errors.New("source check point not equal to previous justified checkpoint")
}
}
if err := helpers.ValidateSlotTargetEpoch(att.Data); err != nil {
return err
}
s := att.Data.Slot
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
if !minInclusionCheck {
return nil, fmt.Errorf(
return fmt.Errorf(
"attestation slot %d + inclusion delay %d > state slot %d",
s,
params.BeaconConfig().MinAttestationInclusionDelay,
@@ -146,7 +151,7 @@ func ProcessAttestationNoVerifySignature(
)
}
if !epochInclusionCheck {
return nil, fmt.Errorf(
return fmt.Errorf(
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
beaconState.Slot(),
s,
@@ -155,17 +160,47 @@ func ProcessAttestationNoVerifySignature(
}
activeValidatorCount, err := helpers.ActiveValidatorCount(beaconState, att.Data.Target.Epoch)
if err != nil {
return nil, err
return err
}
c := helpers.SlotCommitteeCount(activeValidatorCount)
if att.Data.CommitteeIndex >= c {
return nil, fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
if uint64(att.Data.CommitteeIndex) >= c {
return fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
}
if err := helpers.VerifyAttestationBitfieldLengths(beaconState, att); err != nil {
return nil, errors.Wrap(err, "could not verify attestation bitfields")
return errors.Wrap(err, "could not verify attestation bitfields")
}
// Verify attesting indices are correct.
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, att, committee)
if err != nil {
return err
}
return attestationutil.IsValidAttestationIndices(ctx, indexedAtt)
}
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerifySignature(
ctx context.Context,
beaconState iface.BeaconState,
att *ethpb.Attestation,
) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
defer span.End()
if err := VerifyAttestationNoVerifySignature(ctx, beaconState, att); err != nil {
return nil, err
}
currEpoch := helpers.CurrentEpoch(beaconState)
data := att.Data
s := att.Data.Slot
proposerIndex, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, err
@@ -177,112 +212,33 @@ func ProcessAttestationNoVerifySignature(
ProposerIndex: proposerIndex,
}
var ffgSourceEpoch uint64
var ffgSourceRoot []byte
var ffgTargetEpoch uint64
if data.Target.Epoch == currEpoch {
ffgSourceEpoch = beaconState.CurrentJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.CurrentJustifiedCheckpoint().Root
ffgTargetEpoch = currEpoch
if err := beaconState.AppendCurrentEpochAttestations(pendingAtt); err != nil {
return nil, err
}
} else {
ffgSourceEpoch = beaconState.PreviousJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.PreviousJustifiedCheckpoint().Root
ffgTargetEpoch = prevEpoch
if err := beaconState.AppendPreviousEpochAttestations(pendingAtt); err != nil {
return nil, err
}
}
if data.Source.Epoch != ffgSourceEpoch {
return nil, fmt.Errorf("expected source epoch %d, received %d", ffgSourceEpoch, data.Source.Epoch)
}
if !bytes.Equal(data.Source.Root, ffgSourceRoot) {
return nil, fmt.Errorf("expected source root %#x, received %#x", ffgSourceRoot, data.Source.Root)
}
if data.Target.Epoch != ffgTargetEpoch {
return nil, fmt.Errorf("expected target epoch %d, received %d", ffgTargetEpoch, data.Target.Epoch)
}
// Verify attesting indices are correct.
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return nil, err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return nil, err
}
return beaconState, nil
}
// VerifyAttestationsSignatures will verify the signatures of the provided attestations. This method performs
// a single BLS verification call to verify the signatures of all of the provided attestations. All
// of the provided attestations must have valid signatures or this method will return an error.
// This method does not determine which attestation signature is invalid, only that one or more
// attestation signatures were not valid.
func VerifyAttestationsSignatures(ctx context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationsSignatures")
defer span.End()
atts := b.Block.Body.Attestations
span.AddAttributes(trace.Int64Attribute("attestations", int64(len(atts))))
if len(atts) == 0 {
return nil
}
fork := beaconState.Fork()
gvr := beaconState.GenesisValidatorRoot()
dt := params.BeaconConfig().DomainBeaconAttester
// Split attestations by fork. Note: the signature domain will differ based on the fork.
var preForkAtts []*ethpb.Attestation
var postForkAtts []*ethpb.Attestation
for _, a := range atts {
if helpers.SlotToEpoch(a.Data.Slot) < fork.Epoch {
preForkAtts = append(preForkAtts, a)
} else {
postForkAtts = append(postForkAtts, a)
}
}
// Check attestations from before the fork.
if fork.Epoch > 0 { // Check to prevent underflow.
prevDomain, err := helpers.Domain(fork, fork.Epoch-1, dt, gvr)
if err != nil {
return err
}
if err := verifyAttestationsSigWithDomain(ctx, beaconState, preForkAtts, prevDomain); err != nil {
return err
}
} else if len(preForkAtts) > 0 {
// This is a sanity check that preForkAtts were not ignored when fork.Epoch == 0. This
// condition is not possible, but it doesn't hurt to check anyway.
return errors.New("some attestations were not verified from previous fork before genesis")
}
// Then check attestations from after the fork.
currDomain, err := helpers.Domain(fork, fork.Epoch, dt, gvr)
if err != nil {
return err
}
return verifyAttestationsSigWithDomain(ctx, beaconState, postForkAtts, currDomain)
}
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
// the signature in that attestation.
func VerifyAttestationSignature(ctx context.Context, beaconState *stateTrie.BeaconState, att *ethpb.Attestation) error {
if att == nil || att.Data == nil || att.AggregationBits.Count() == 0 {
return fmt.Errorf("nil or missing attestation data: %v", att)
func VerifyAttestationSignature(ctx context.Context, beaconState iface.ReadOnlyBeaconState, att *ethpb.Attestation) error {
if err := helpers.ValidateNilAttestation(att); err != nil {
return err
}
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, att, committee)
if err != nil {
return err
}
return VerifyIndexedAttestation(ctx, beaconState, indexedAtt)
}
@@ -302,21 +258,26 @@ func VerifyAttestationSignature(ctx context.Context, beaconState *stateTrie.Beac
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
// signing_root = compute_signing_root(indexed_attestation.data, domain)
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.BeaconState, indexedAtt *ethpb.IndexedAttestation) error {
func VerifyIndexedAttestation(ctx context.Context, beaconState iface.ReadOnlyBeaconState, indexedAtt *ethpb.IndexedAttestation) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyIndexedAttestation")
defer span.End()
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
domain, err := helpers.Domain(beaconState.Fork(), indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
domain, err := helpers.Domain(
beaconState.Fork(),
indexedAtt.Data.Target.Epoch,
params.BeaconConfig().DomainBeaconAttester,
beaconState.GenesisValidatorRoot(),
)
if err != nil {
return err
}
indices := indexedAtt.AttestingIndices
var pubkeys []bls.PublicKey
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
pubkeyAtIdx := beaconState.PubkeyAtIndex(types.ValidatorIndex(indices[i]))
pk, err := bls.PublicKeyFromBytes(pubkeyAtIdx[:])
if err != nil {
return errors.Wrap(err, "could not deserialize validator public key")
@@ -325,55 +286,3 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.Beacon
}
return attestationutil.VerifyIndexedAttestationSig(ctx, indexedAtt, pubkeys, domain)
}
// Inner method to verify attestations. This abstraction allows for the domain to be provided as an
// argument.
func verifyAttestationsSigWithDomain(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) error {
if len(atts) == 0 {
return nil
}
set, err := createAttestationSignatureSet(ctx, beaconState, atts, domain)
if err != nil {
return err
}
verify, err := set.Verify()
if err != nil {
return errors.Errorf("got error in multiple verification: %v", err)
}
if !verify {
return errors.New("one or more attestation signatures did not verify")
}
return nil
}
// VerifyAttSigUseCheckPt uses the checkpoint info object to verify attestation signature.
func VerifyAttSigUseCheckPt(ctx context.Context, c *pb.CheckPtInfo, att *ethpb.Attestation) error {
if att == nil || att.Data == nil || att.AggregationBits.Count() == 0 {
return fmt.Errorf("nil or missing attestation data: %v", att)
}
seed := bytesutil.ToBytes32(c.Seed)
committee, err := helpers.BeaconCommittee(c.ActiveIndices, seed, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
domain, err := helpers.Domain(c.Fork, indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, c.GenesisRoot)
if err != nil {
return err
}
indices := indexedAtt.AttestingIndices
var pubkeys []bls.PublicKey
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := c.PubKeys[indices[i]]
pk, err := bls.PublicKeyFromBytes(pubkeyAtIdx)
if err != nil {
return errors.Wrap(err, "could not deserialize validator public key")
}
pubkeys = append(pubkeys, pk)
}
return attestationutil.VerifyIndexedAttestationSig(ctx, indexedAtt, pubkeys, domain)
}

View File

@@ -5,10 +5,14 @@ import (
"io/ioutil"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -33,7 +37,7 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
if err := spb.UnmarshalSSZ(stateData); err != nil {
t.Fatal(err)
}
st, err := state.InitializeFromProtoUnsafe(spb)
st, err := v1.InitializeFromProtoUnsafe(spb)
if err != nil {
t.Fatal(err)
}
@@ -42,3 +46,35 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
_, err = blocks.ProcessAttestationNoVerifySignature(ctx, st, att)
require.ErrorContains(t, "committee index 1 >= committee count 1", err)
}
// Regression introduced in https://github.com/prysmaticlabs/prysm/pull/8566.
func TestVerifyAttestationNoVerifySignature_IncorrectSourceEpoch(t *testing.T) {
// Attestation with an empty signature
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 99, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NotEqual(t, nil, err)
}

View File

@@ -5,12 +5,14 @@ import (
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/aggregation"
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
@@ -24,12 +26,12 @@ import (
func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
attestations := []*ethpb.Attestation{
{
testutil.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Slot: 5,
},
},
}),
}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
@@ -45,15 +47,15 @@ func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
params.BeaconConfig().MinAttestationInclusionDelay,
beaconState.Slot(),
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
att := &ethpb.Attestation{
att := testutil.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0}}}
Target: &ethpb.Checkpoint{Epoch: 0}}})
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
@@ -67,7 +69,7 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
@@ -75,19 +77,18 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
helpers.PrevEpoch(beaconState),
helpers.CurrentEpoch(beaconState),
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
aggBits := bitfield.NewBitlist(3)
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
AggregationBits: bitfield.Bitlist{0x09},
},
}
b := testutil.NewBeaconBlock()
@@ -101,25 +102,14 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.CurrentEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
want := "source check point not equal to current justified checkpoint"
_, err := blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
want = fmt.Sprintf(
"expected source root %#x, received %#x",
beaconState.CurrentJustifiedCheckpoint().Root,
attestations[0].Data.Source.Root,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -145,31 +135,20 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
},
}
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch + params.BeaconConfig().MinAttestationInclusionDelay)
err := beaconState.SetSlot(beaconState.Slot() + 2*params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err)
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.PrevEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
want := "source check point not equal to previous justified checkpoint"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.CurrentEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
want = fmt.Sprintf(
"expected source root %#x, received %#x",
beaconState.CurrentJustifiedCheckpoint().Root,
attestations[0].Data.Source.Root,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -197,10 +176,10 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
assert.ErrorContains(t, expected, err)
}
@@ -211,24 +190,22 @@ func TestProcessAttestations_OK(t *testing.T) {
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
att := testutil.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
Signature: make([]byte, 96),
}
})
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices := attestationutil.AttestingIndices(att.AggregationBits, committee)
attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
@@ -245,21 +222,19 @@ func TestProcessAttestations_OK(t *testing.T) {
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
assert.NoError(t, err)
}
func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
data := &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
BeaconBlockRoot: make([]byte, 32),
}
aggBits1 := bitfield.NewBitlist(4)
data := testutil.HydrateAttestationData(&ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
})
aggBits1 := bitfield.NewBitlist(3)
aggBits1.SetBitAt(0, true)
aggBits1.SetBitAt(1, true)
aggBits1.SetBitAt(2, true)
att1 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits1,
@@ -268,11 +243,11 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = bytesutil.PadTo([]byte("hello-world"), 32)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices1 := attestationutil.AttestingIndices(att1.AggregationBits, committee)
attestingIndices1, err := attestationutil.AttestingIndices(att1.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices1))
for i, indice := range attestingIndices1 {
@@ -284,10 +259,9 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
aggBits2 := bitfield.NewBitlist(4)
aggBits2 := bitfield.NewBitlist(3)
aggBits2.SetBitAt(1, true)
aggBits2.SetBitAt(2, true)
aggBits2.SetBitAt(3, true)
att2 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits2,
@@ -295,7 +269,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices2 := attestationutil.AttestingIndices(att2.AggregationBits, committee)
attestingIndices2, err := attestationutil.AttestingIndices(att2.AggregationBits, committee)
require.NoError(t, err)
sigs = make([]bls.Signature, len(attestingIndices2))
for i, indice := range attestingIndices2 {
@@ -316,11 +290,10 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
data := &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
}
data := testutil.HydrateAttestationData(&ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
})
aggBits1 := bitfield.NewBitlist(9)
aggBits1.SetBitAt(0, true)
aggBits1.SetBitAt(1, true)
@@ -333,11 +306,11 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices1 := attestationutil.AttestingIndices(att1.AggregationBits, committee)
attestingIndices1, err := attestationutil.AttestingIndices(att1.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices1))
for i, indice := range attestingIndices1 {
@@ -360,7 +333,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices2 := attestationutil.AttestingIndices(att2.AggregationBits, committee)
attestingIndices2, err := attestationutil.AttestingIndices(att2.AggregationBits, committee)
require.NoError(t, err)
sigs = make([]bls.Signature, len(attestingIndices2))
for i, indice := range attestingIndices2 {
@@ -380,21 +353,21 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch(t *testing.T) {
func TestVerifyAttestationNoVerifySignature_IncorrectSlotTargetEpoch(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 1)
att := &ethpb.Attestation{
att := testutil.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Slot: params.BeaconConfig().SlotsPerEpoch,
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
}
wanted := fmt.Sprintf("data slot is not in the same epoch as target %d != %d", helpers.SlotToEpoch(att.Data.Slot), att.Data.Target.Epoch)
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
})
wanted := "slot 32 does not match target epoch 0"
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.ErrorContains(t, wanted, err)
}
@@ -423,13 +396,44 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
_, err = blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
func TestVerifyAttestationNoVerifySignature_OK(t *testing.T) {
// Attestation with an empty signature
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
func TestVerifyAttestationNoVerifySignature_BadAttIdx(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
@@ -449,8 +453,8 @@ func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.ErrorContains(t, "committee index 100 >= committee count 1", err)
}
@@ -463,7 +467,7 @@ func TestConvertToIndexed_OK(t *testing.T) {
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := v1.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
@@ -478,24 +482,20 @@ func TestConvertToIndexed_OK(t *testing.T) {
wantedAttestingIndices: []uint64{43, 47},
},
{
aggregationBitfield: bitfield.Bitlist{0x03},
aggregationBitfield: bitfield.Bitlist{0x05},
wantedAttestingIndices: []uint64{47},
},
{
aggregationBitfield: bitfield.Bitlist{0x01},
aggregationBitfield: bitfield.Bitlist{0x04},
wantedAttestingIndices: []uint64{},
},
}
var sig [96]byte
copy(sig[:], "signed")
attestation := &ethpb.Attestation{
attestation := testutil.HydrateAttestation(&ethpb.Attestation{
Signature: sig[:],
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
}
})
for _, tt := range tests {
attestation.AggregationBits = tt.aggregationBitfield
wanted := &ethpb.IndexedAttestation{
@@ -506,13 +506,14 @@ func TestConvertToIndexed_OK(t *testing.T) {
committee, err := helpers.BeaconCommitteeFromState(state, attestation.Data.Slot, attestation.Data.CommitteeIndex)
require.NoError(t, err)
ia := attestationutil.ConvertToIndexed(context.Background(), attestation, committee)
ia, err := attestationutil.ConvertToIndexed(context.Background(), attestation, committee)
require.NoError(t, err)
assert.DeepEqual(t, wanted, ia, "Convert attestation to indexed attestation didn't result as wanted")
}
}
func TestVerifyIndexedAttestation_OK(t *testing.T) {
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
@@ -524,7 +525,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := v1.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
Fork: &pb.Fork{
@@ -539,58 +540,39 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
attestation *ethpb.IndexedAttestation
}{
{attestation: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: 2,
Root: make([]byte, 32),
},
Source: &ethpb.Checkpoint{
Root: make([]byte, 32),
},
BeaconBlockRoot: make([]byte, 32),
},
Source: &ethpb.Checkpoint{},
}),
AttestingIndices: []uint64{1},
Signature: make([]byte, 96),
}},
{attestation: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: 1,
Root: make([]byte, 32),
},
Source: &ethpb.Checkpoint{
Root: make([]byte, 32),
},
BeaconBlockRoot: make([]byte, 32),
},
}),
AttestingIndices: []uint64{47, 99, 101},
Signature: make([]byte, 96),
}},
{attestation: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: 4,
Root: make([]byte, 32),
},
Source: &ethpb.Checkpoint{
Root: make([]byte, 32),
},
BeaconBlockRoot: make([]byte, 32),
},
}),
AttestingIndices: []uint64{21, 72},
Signature: make([]byte, 96),
}},
{attestation: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: 7,
Root: make([]byte, 32),
},
Source: &ethpb.Checkpoint{
Root: make([]byte, 32),
},
BeaconBlockRoot: make([]byte, 32),
},
}),
AttestingIndices: []uint64{100, 121, 122},
Signature: make([]byte, 96),
}},
@@ -624,21 +606,21 @@ func TestValidateIndexedAttestation_AboveMaxLength(t *testing.T) {
indexedAtt1.AttestingIndices[i] = i
indexedAtt1.Data = &ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: i,
Epoch: types.Epoch(i),
},
}
}
want := "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE"
err := blocks.VerifyIndexedAttestation(context.Background(), &stateTrie.BeaconState{}, indexedAtt1)
err := blocks.VerifyIndexedAttestation(context.Background(), &v1.BeaconState{}, indexedAtt1)
assert.ErrorContains(t, want, err)
}
func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
beaconState, keys := testutil.DeterministicGenesisState(t, 1000)
beaconState, keys := testutil.DeterministicGenesisState(t, 128)
sig := keys[0].Sign([]byte{'t', 'e', 's', 't'})
list := bitfield.Bitlist{0b11111111}
list := bitfield.Bitlist{0b11111}
var atts []*ethpb.Attestation
for i := uint64(0); i < 1000; i++ {
atts = append(atts, &ethpb.Attestation{
@@ -656,7 +638,7 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
assert.ErrorContains(t, want, err)
atts = []*ethpb.Attestation{}
list = bitfield.Bitlist{0b00000000}
list = bitfield.Bitlist{0b10000}
for i := uint64(0); i < 1000; i++ {
atts = append(atts, &ethpb.Attestation{
Data: &ethpb.AttestationData{
@@ -676,79 +658,9 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
assert.ErrorContains(t, want, err)
}
func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st := testutil.NewBeaconState()
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
// In this test, att1 is from the prior fork and att2 is from the new fork.
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
@@ -760,7 +672,8 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
}
}
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(35))
require.NoError(t, st.SetValidators(validators))
require.NoError(t, st.SetFork(&pb.Fork{
@@ -771,17 +684,12 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := &ethpb.Attestation{
att1 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: 1,
},
Signature: make([]byte, 96),
}
})
prevDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch-1, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, prevDomain)
@@ -795,17 +703,13 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
comm2, err := helpers.BeaconCommitteeFromState(st, 1*params.BeaconConfig().SlotsPerEpoch+1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
att2 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1*params.BeaconConfig().SlotsPerEpoch + 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: 1*params.BeaconConfig().SlotsPerEpoch + 1,
CommitteeIndex: 1,
},
Signature: make([]byte, 96),
}
})
currDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err = helpers.ComputeSigningRoot(att2.Data, currDomain)
@@ -816,15 +720,11 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
@@ -836,23 +736,19 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
}
}
st := testutil.NewBeaconState()
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := &ethpb.Attestation{
att1 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: 1,
},
Signature: make([]byte, 96),
}
})
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
@@ -866,17 +762,13 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
att2 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: 1,
CommitteeIndex: 1,
},
Signature: make([]byte, 96),
}
})
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
@@ -892,3 +784,64 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
}
func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {
ctx := context.Background()
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
require.NoError(t, st.SetFork(&pb.Fork{Epoch: 1, CurrentVersion: []byte{0, 1, 2, 3}, PreviousVersion: []byte{0, 1, 1, 1}}))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
})
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
_, err = blocks.AttestationSignatureSet(ctx, st, []*ethpb.Attestation{att1, att2})
require.NoError(t, err)
}

View File

@@ -5,11 +5,12 @@ import (
"sort"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/slashutil"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
@@ -34,15 +35,11 @@ import (
// assert slashed_any
func ProcessAttesterSlashings(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
for idx, slashing := range body.AttesterSlashings {
beaconState iface.BeaconState,
slashings []*ethpb.AttesterSlashing,
slashFunc slashValidatorFunc,
) (iface.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)
}
@@ -53,14 +50,14 @@ func ProcessAttesterSlashings(
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
var err error
var slashedAny bool
var val stateTrie.ReadOnlyValidator
var val iface.ReadOnlyValidator
for _, validatorIndex := range slashableIndices {
val, err = beaconState.ValidatorAtIndexReadOnly(validatorIndex)
val, err = beaconState.ValidatorAtIndexReadOnly(types.ValidatorIndex(validatorIndex))
if err != nil {
return nil, err
}
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
beaconState, err = v.SlashValidator(beaconState, validatorIndex)
beaconState, err = slashFunc(beaconState, types.ValidatorIndex(validatorIndex))
if err != nil {
return nil, errors.Wrapf(err, "could not slash validator index %d",
validatorIndex)
@@ -76,7 +73,7 @@ func ProcessAttesterSlashings(
}
// VerifyAttesterSlashing validates the attestation data in both attestations in the slashing object.
func VerifyAttesterSlashing(ctx context.Context, beaconState *stateTrie.BeaconState, slashing *ethpb.AttesterSlashing) error {
func VerifyAttesterSlashing(ctx context.Context, beaconState iface.ReadOnlyBeaconState, slashing *ethpb.AttesterSlashing) error {
if slashing == nil {
return errors.New("nil slashing")
}
@@ -120,7 +117,10 @@ func IsSlashableAttestationData(data1, data2 *ethpb.AttestationData) bool {
return false
}
isDoubleVote := !attestationutil.AttDataIsEqual(data1, data2) && data1.Target.Epoch == data2.Target.Epoch
isSurroundVote := data1.Source.Epoch < data2.Source.Epoch && data2.Target.Epoch < data1.Target.Epoch
att1 := &ethpb.IndexedAttestation{Data: data1}
att2 := &ethpb.IndexedAttestation{Data: data2}
// Check if att1 is surrounding att2.
isSurroundVote := slashutil.IsSurround(att1, att2)
return isDoubleVote || isSurroundVote
}

View File

@@ -4,11 +4,13 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -18,16 +20,14 @@ import (
)
func TestSlashableAttestationData_CanSlash(t *testing.T) {
att1 := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
BeaconBlockRoot: make([]byte, 32),
}
att2 := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'B'}, 32)},
BeaconBlockRoot: make([]byte, 32),
}
att1 := testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
})
att2 := testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'B'}, 32)},
})
assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable")
att1.Target.Epoch = 4
att1.Source.Epoch = 2
@@ -36,30 +36,18 @@ func TestSlashableAttestationData_CanSlash(t *testing.T) {
}
func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
slashings := []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
Signature: make([]byte, 96),
},
Attestation_2: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
Signature: make([]byte, 96),
},
},
}
var registry []*ethpb.Validator
currentSlot := uint64(0)
slashings := []*ethpb.AttesterSlashing{{
Attestation_1: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{}),
Attestation_2: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
Target: &ethpb.Checkpoint{Epoch: 1}},
})}}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
var registry []*ethpb.Validator
currentSlot := types.Slot(0)
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
@@ -70,15 +58,15 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
AttesterSlashings: slashings,
},
}
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
assert.ErrorContains(t, "attestations are not slashable", err)
}
func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T) {
var registry []*ethpb.Validator
currentSlot := uint64(0)
currentSlot := types.Slot(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
@@ -86,24 +74,15 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
slashings := []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
Attestation_1: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Epoch: 1},
},
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
Attestation_2: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
}),
Attestation_2: testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
}),
},
}
@@ -114,24 +93,22 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
},
}
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
assert.ErrorContains(t, "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE", err)
}
func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
for _, vv := range beaconState.Validators() {
vv.WithdrawableEpoch = 1 * params.BeaconConfig().SlotsPerEpoch
vv.WithdrawableEpoch = types.Epoch(params.BeaconConfig().SlotsPerEpoch)
}
att1 := &ethpb.IndexedAttestation{
att1 := testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Epoch: 1},
},
AttestingIndices: []uint64{0, 1},
}
})
domain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
require.NoError(t, err)
signingRoot, err := helpers.ComputeSigningRoot(att1.Data, domain)
@@ -141,14 +118,9 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1})
att1.Signature = aggregateSig.Marshal()
att2 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
att2 := testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
AttestingIndices: []uint64{0, 1},
}
})
signingRoot, err = helpers.ComputeSigningRoot(att2.Data, domain)
assert.NoError(t, err, "Could not get signing root of beacon block header")
sig0 = privKeys[0].Sign(signingRoot[:])
@@ -173,7 +145,7 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
},
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
require.NoError(t, err)
newRegistry := newState.Validators()

View File

@@ -5,9 +5,12 @@ import (
"testing"
fuzz "github.com/google/gofuzz"
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
types "github.com/prysmaticlabs/eth2-types"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -21,7 +24,7 @@ func TestFuzzProcessAttestationNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(att)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessAttestationNoVerifySignature(ctx, s, att)
_ = err
@@ -37,9 +40,9 @@ func TestFuzzProcessBlockHeader_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeader(context.Background(), s, block)
_, err = ProcessBlockHeader(context.Background(), s, wrapper.WrappedPhase0SignedBeaconBlock(block))
_ = err
}
}
@@ -70,14 +73,14 @@ func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
func TestFuzzProcessEth1DataInBlock_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
b := &eth.SignedBeaconBlock{}
state := &stateTrie.BeaconState{}
e := &eth.Eth1Data{}
state := &v1.BeaconState{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := ProcessEth1DataInBlock(context.Background(), state, b)
fuzzer.Fuzz(e)
s, err := ProcessEth1DataInBlock(context.Background(), state, e)
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and block: %v", s, err, state, b)
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and eth1data: %v", s, err, state, e)
}
}
}
@@ -102,7 +105,7 @@ func TestFuzzEth1DataHasEnoughSupport_10000(t *testing.T) {
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(eth1data)
fuzzer.Fuzz(&stateVotes)
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{
s, err := v1.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: stateVotes,
})
require.NoError(t, err)
@@ -120,9 +123,9 @@ func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeaderNoVerify(s, block)
_, err = ProcessBlockHeaderNoVerify(s, block.Slot, block.ProposerIndex, block.ParentRoot, []byte{})
_ = err
}
}
@@ -135,9 +138,9 @@ func TestFuzzProcessRandao_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandao(context.Background(), s, b)
r, err := ProcessRandao(context.Background(), s, wrapper.WrappedPhase0SignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
@@ -152,9 +155,9 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandaoNoVerify(s, blockBody)
r, err := ProcessRandaoNoVerify(s, blockBody.RandaoReveal)
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, blockBody)
}
@@ -164,16 +167,16 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
func TestFuzzProcessProposerSlashings_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
p := &eth.ProposerSlashing{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
fuzzer.Fuzz(p)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessProposerSlashings(ctx, s, b)
r, err := ProcessProposerSlashings(ctx, s, []*eth.ProposerSlashing{p}, v.SlashValidator)
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and slashing: %v", r, err, state, p)
}
}
}
@@ -185,7 +188,7 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(proposerSlashing)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyProposerSlashing(s, proposerSlashing)
_ = err
@@ -195,16 +198,16 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
func TestFuzzProcessAttesterSlashings_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
a := &eth.AttesterSlashing{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
fuzzer.Fuzz(a)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttesterSlashings(ctx, s, b)
r, err := ProcessAttesterSlashings(ctx, s, []*eth.AttesterSlashing{a}, v.SlashValidator)
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and slashing: %v", r, err, state, a)
}
}
}
@@ -217,7 +220,7 @@ func TestFuzzVerifyAttesterSlashing_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attesterSlashing)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttesterSlashing(ctx, s, attesterSlashing)
_ = err
@@ -254,9 +257,9 @@ func TestFuzzProcessAttestations_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestations(ctx, s, b)
r, err := ProcessAttestations(ctx, s, wrapper.WrappedPhase0SignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
@@ -271,9 +274,9 @@ func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, b)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, wrapper.WrappedPhase0SignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
@@ -288,7 +291,7 @@ func TestFuzzProcessAttestation_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestation(ctx, s, attestation)
if err != nil && r != nil {
@@ -305,7 +308,7 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(idxAttestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyIndexedAttestation(ctx, s, idxAttestation)
_ = err
@@ -320,7 +323,7 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
@@ -330,16 +333,18 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
deposits := make([]*eth.Deposit, 100)
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
for i := range deposits {
fuzzer.Fuzz(deposits[i])
}
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposits(ctx, s, b)
r, err := ProcessDeposits(ctx, s, deposits)
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, deposits)
}
}
}
@@ -353,7 +358,7 @@ func TestFuzzProcessPreGenesisDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessPreGenesisDeposits(ctx, s, []*eth.Deposit{deposit})
if err != nil && r != nil {
@@ -370,7 +375,7 @@ func TestFuzzProcessDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposit(s, deposit, true)
if err != nil && r != nil {
@@ -386,7 +391,7 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = verifyDeposit(s, deposit)
_ = err
@@ -396,16 +401,16 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
e := &eth.SignedVoluntaryExit{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
fuzzer.Fuzz(e)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(ctx, s, b)
r, err := ProcessVoluntaryExits(ctx, s, []*eth.SignedVoluntaryExit{e})
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and exit: %v", r, err, state, e)
}
}
}
@@ -413,15 +418,15 @@ func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
e := &eth.SignedVoluntaryExit{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
fuzzer.Fuzz(e)
s, err := v1.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(context.Background(), s, b)
r, err := ProcessVoluntaryExits(context.Background(), s, []*eth.SignedVoluntaryExit{e})
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, e)
}
}
}
@@ -429,9 +434,9 @@ func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
func TestFuzzVerifyExit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
ve := &eth.SignedVoluntaryExit{}
val := stateTrie.ReadOnlyValidator{}
val := v1.ReadOnlyValidator{}
fork := &pb.Fork{}
var slot uint64
var slot types.Slot
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(ve)

View File

@@ -4,9 +4,11 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -15,10 +17,10 @@ import (
)
func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
testutil.ResetCache()
beaconState, privKeys := testutil.DeterministicGenesisState(t, 5500)
for _, vv := range beaconState.Validators() {
vv.WithdrawableEpoch = 1 * params.BeaconConfig().SlotsPerEpoch
vv.WithdrawableEpoch = types.Epoch(params.BeaconConfig().SlotsPerEpoch)
}
// This set of indices is very similar to the one from our sapphire testnet
// when close to 100 validators were incorrectly slashed. The set is from 0 -5500,
@@ -38,11 +40,7 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
root1 := [32]byte{'d', 'o', 'u', 'b', 'l', 'e', '1'}
att1 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root1[:]},
BeaconBlockRoot: make([]byte, 32),
},
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: 0, Root: root1[:]}}),
AttestingIndices: setA,
Signature: make([]byte, 96),
}
@@ -60,11 +58,9 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
root2 := [32]byte{'d', 'o', 'u', 'b', 'l', 'e', '2'}
att2 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root2[:]},
BeaconBlockRoot: make([]byte, 32),
},
Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
Target: &ethpb.Checkpoint{Root: root2[:]},
}),
AttestingIndices: setB,
Signature: make([]byte, 96),
}
@@ -95,7 +91,7 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
},
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
require.NoError(t, err)
newRegistry := newState.Validators()
if !newRegistry[expectedSlashedVal].Slashed {

View File

@@ -5,11 +5,10 @@ import (
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/depositutil"
@@ -21,15 +20,23 @@ import (
// ProcessPreGenesisDeposits processes a deposit for the beacon state before chainstart.
func ProcessPreGenesisDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
deposits []*ethpb.Deposit,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
var err error
beaconState, err = ProcessDeposits(ctx, beaconState, &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{Deposits: deposits}}})
beaconState, err = ProcessDeposits(ctx, beaconState, deposits)
if err != nil {
return nil, errors.Wrap(err, "could not process deposit")
}
beaconState, err = ActivateValidatorWithEffectiveBalance(beaconState, deposits)
if err != nil {
return nil, err
}
return beaconState, nil
}
// ActivateValidatorWithEffectiveBalance updates validator's effective balance, and if it's above MaxEffectiveBalance, validator becomes active in genesis.
func ActivateValidatorWithEffectiveBalance(beaconState iface.BeaconState, deposits []*ethpb.Deposit) (iface.BeaconState, error) {
for _, deposit := range deposits {
pubkey := deposit.Data.PublicKey
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubkey))
@@ -68,33 +75,21 @@ func ProcessPreGenesisDeposits(
// process_deposit(state, deposit)
func ProcessDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
deposits := b.Block.Body.Deposits
var err error
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return nil, err
}
beaconState iface.BeaconState,
deposits []*ethpb.Deposit,
) (iface.BeaconState, error) {
// Attempt to verify all deposit signatures at once, if this fails then fall back to processing
// individual deposits with signature verification enabled.
var verifySignature bool
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
log.WithError(err).Debug("Failed to verify deposit data, verifying signatures individually")
verifySignature = true
batchVerified, err := BatchVerifyDepositsSignatures(ctx, deposits)
if err != nil {
return nil, err
}
for _, deposit := range deposits {
if deposit == nil || deposit.Data == nil {
return nil, errors.New("got a nil deposit in block")
}
beaconState, err = ProcessDeposit(beaconState, deposit, verifySignature)
beaconState, err = ProcessDeposit(beaconState, deposit, batchVerified)
if err != nil {
return nil, errors.Wrapf(err, "could not process deposit from %#x", bytesutil.Trunc(deposit.Data.PublicKey))
}
@@ -102,6 +97,22 @@ func ProcessDeposits(
return beaconState, nil
}
// BatchVerifyDepositsSignatures batch verifies deposit signatures.
func BatchVerifyDepositsSignatures(ctx context.Context, deposits []*ethpb.Deposit) (bool, error) {
var err error
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return false, err
}
verified := false
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
log.WithError(err).Debug("Failed to batch verify deposits signatures, will try individual verify")
verified = true
}
return verified, nil
}
// ProcessDeposit takes in a deposit object and inserts it
// into the registry as a new validator or balance change.
//
@@ -141,7 +152,7 @@ func ProcessDeposits(
// # Increase balance by deposit amount
// index = ValidatorIndex(validator_pubkeys.index(pubkey))
// increase_balance(state, index, amount)
func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (*stateTrie.BeaconState, error) {
func ProcessDeposit(beaconState iface.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (iface.BeaconState, error) {
if err := verifyDeposit(beaconState, deposit); err != nil {
if deposit == nil || deposit.Data == nil {
return nil, err
@@ -192,7 +203,7 @@ func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit,
return beaconState, nil
}
func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) error {
func verifyDeposit(beaconState iface.ReadOnlyBeaconState, deposit *ethpb.Deposit) error {
// Verify Merkle proof of deposit and deposit trie root.
if deposit == nil || deposit.Data == nil {
return errors.New("received nil deposit or nil deposit data")
@@ -223,7 +234,6 @@ func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) e
return nil
}
// Deprecated: This method uses deprecated ssz.SigningRoot.
func verifyDepositDataSigningRoot(obj *ethpb.Deposit_Data, domain []byte) error {
return depositutil.VerifyDepositSignature(obj, domain)
}
@@ -248,19 +258,16 @@ func verifyDepositDataWithDomain(ctx context.Context, deps []*ethpb.Deposit, dom
}
pks[i] = dpk
sigs[i] = dep.Data.Signature
root, err := ssz.SigningRoot(dep.Data)
depositMessage := &pb.DepositMessage{
PublicKey: dep.Data.PublicKey,
WithdrawalCredentials: dep.Data.WithdrawalCredentials,
Amount: dep.Data.Amount,
}
sr, err := helpers.ComputeSigningRoot(depositMessage, domain)
if err != nil {
return errors.Wrap(err, "could not get signing root")
return err
}
signingData := &pb.SigningData{
ObjectRoot: root[:],
Domain: domain,
}
ctrRoot, err := signingData.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get container root")
}
msgs[i] = ctrRoot
msgs[i] = sr
}
verify, err := bls.VerifyMultipleSignatures(sigs, msgs, pks)
if err != nil {

View File

@@ -4,11 +4,12 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -20,7 +21,7 @@ import (
func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
// Same validator created 3 valid deposits within the same block
testutil.ResetCache()
dep, _, err := testutil.DeterministicDepositsAndKeysSameValidator(3)
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
@@ -39,7 +40,7 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -49,7 +50,7 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Expected block deposits to process correctly")
assert.Equal(t, 2, len(newState.Validators()), "Incorrect validator count")
@@ -79,7 +80,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
Deposits: []*ethpb.Deposit{deposit},
},
}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{0},
BlockHash: []byte{1},
@@ -87,7 +88,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
})
require.NoError(t, err)
want := "deposit root did not verify"
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b)
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
assert.ErrorContains(t, want, err)
}
@@ -110,7 +111,7 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -120,7 +121,7 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Expected block deposits to process correctly")
if newState.Balances()[1] != dep[0].Data.Amount {
t.Errorf(
@@ -173,7 +174,7 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
}
balances := []uint64{0, 50}
root := depositTrie.Root()
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: &ethpb.Eth1Data{
@@ -182,13 +183,13 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Process deposit failed")
assert.Equal(t, uint64(1000+50), newState.Balances()[1], "Expected balance at index 1 to be 1050")
}
func TestProcessDeposit_AddsNewValidatorDeposit(t *testing.T) {
//Similar to TestProcessDeposits_AddsNewValidatorDeposit except that this test directly calls ProcessDeposit
// Similar to TestProcessDeposits_AddsNewValidatorDeposit except that this test directly calls ProcessDeposit
dep, _, err := testutil.DeterministicDepositsAndKeys(1)
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
@@ -201,7 +202,7 @@ func TestProcessDeposit_AddsNewValidatorDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -243,7 +244,7 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -274,12 +275,9 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
}
func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
testutil.ResetCache()
dep, _, err := testutil.DeterministicDepositsAndKeys(100)
require.NoError(t, err)
defer func() {
testutil.ResetCache()
}()
dep[0].Data.Signature = make([]byte, 96)
trie, _, err := testutil.DepositTrieFromDeposits(dep)
require.NoError(t, err)
@@ -301,7 +299,7 @@ func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -318,11 +316,11 @@ func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
require.Equal(t, false, ok, "bad pubkey should not exist in state")
for i := 1; i < newState.NumValidators(); i++ {
val, err := newState.ValidatorAtIndex(uint64(i))
val, err := newState.ValidatorAtIndex(types.ValidatorIndex(i))
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalance, val.EffectiveBalance, "unequal effective balance")
require.Equal(t, uint64(0), val.ActivationEpoch)
require.Equal(t, uint64(0), val.ActivationEligibilityEpoch)
require.Equal(t, types.Epoch(0), val.ActivationEpoch)
require.Equal(t, types.Epoch(0), val.ActivationEligibilityEpoch)
}
if newState.Eth1DepositIndex() != 100 {
t.Errorf(

View File

@@ -5,8 +5,9 @@ import (
"context"
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -18,24 +19,20 @@ import (
// def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
// state.eth1_data_votes.append(body.eth1_data)
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
// state.latest_eth1_data = body.eth1_data
func ProcessEth1DataInBlock(_ context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) (*stateTrie.BeaconState, error) {
block := b.Block
if beaconState == nil {
// state.eth1_data = body.eth1_data
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, eth1Data *ethpb.Eth1Data) (iface.BeaconState, error) {
if beaconState == nil || beaconState.IsNil() {
return nil, errors.New("nil state")
}
if block == nil || block.Body == nil {
return nil, errors.New("nil block or block withought body")
}
if err := beaconState.AppendEth1DataVotes(block.Body.Eth1Data); err != nil {
if err := beaconState.AppendEth1DataVotes(eth1Data); err != nil {
return nil, err
}
hasSupport, err := Eth1DataHasEnoughSupport(beaconState, block.Body.Eth1Data)
hasSupport, err := Eth1DataHasEnoughSupport(beaconState, eth1Data)
if err != nil {
return nil, err
}
if hasSupport {
if err := beaconState.SetEth1Data(block.Body.Eth1Data); err != nil {
if err := beaconState.SetEth1Data(eth1Data); err != nil {
return nil, err
}
}
@@ -59,9 +56,9 @@ func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
// eth1 voting period. A vote is cast by including eth1data in a block and part of state processing
// appends eth1data to the state in the Eth1DataVotes list. Iterating through this list checks the
// votes to see if they match the eth1data.
func Eth1DataHasEnoughSupport(beaconState *stateTrie.BeaconState, data *ethpb.Eth1Data) (bool, error) {
func Eth1DataHasEnoughSupport(beaconState iface.ReadOnlyBeaconState, data *ethpb.Eth1Data) (bool, error) {
voteCount := uint64(0)
data = stateTrie.CopyETH1Data(data)
data = copyutil.CopyETH1Data(data)
for _, vote := range beaconState.Eth1DataVotes() {
if AreEth1DataEqual(vote, data) {
@@ -71,6 +68,6 @@ func Eth1DataHasEnoughSupport(beaconState *stateTrie.BeaconState, data *ethpb.Et
// If 50+% majority converged on the same eth1data, then it has enough support to update the
// state.
support := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
return voteCount*2 > support, nil
support := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))
return voteCount*2 > uint64(support), nil
}

View File

@@ -5,16 +5,18 @@ import (
"fmt"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/copyutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"google.golang.org/protobuf/proto"
)
func FakeDeposits(n uint64) []*ethpb.Eth1Data {
@@ -33,10 +35,10 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
stateVotes []*ethpb.Eth1Data
data *ethpb.Eth1Data
hasSupport bool
votingPeriodLength uint64
votingPeriodLength types.Epoch
}{
{
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -44,7 +46,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
hasSupport: true,
votingPeriodLength: 7,
}, {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -52,7 +54,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
hasSupport: false,
votingPeriodLength: 8,
}, {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -69,7 +71,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
c.EpochsPerEth1VotingPeriod = tt.votingPeriodLength
params.OverrideBeaconConfig(c)
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
s, err := v1.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: tt.stateVotes,
})
require.NoError(t, err)
@@ -159,7 +161,7 @@ func TestAreEth1DataEqual(t *testing.T) {
}
func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
beaconState, err := beaconstate.InitializeFromProto(&pb.BeaconState{
beaconState, err := v1.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: []*ethpb.Eth1Data{},
})
require.NoError(t, err)
@@ -174,17 +176,20 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
},
}
period := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
period := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod)))
var ok bool
for i := uint64(0); i < period; i++ {
beaconState, err = blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
processedState, err := blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b.Block.Body.Eth1Data)
require.NoError(t, err)
beaconState, ok = processedState.(*v1.BeaconState)
require.Equal(t, true, ok)
}
newETH1DataVotes := beaconState.Eth1DataVotes()
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), beaconstate.CopyETH1Data(b.Block.Body.Eth1Data)) {
if !proto.Equal(beaconState.Eth1Data(), copyutil.CopyETH1Data(b.Block.Body.Eth1Data)) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
b.Block.Body.Eth1Data,

View File

@@ -5,11 +5,12 @@ import (
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -25,35 +26,28 @@ var ValidatorCannotExitYetMsg = "validator has not been active long enough to ex
// should exit the state's validator registry.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, exit.validator_index)
// initiate_validator_exit(state, voluntary_exit.validator_index)
func ProcessVoluntaryExits(
_ context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
exits := body.VoluntaryExits
beaconState iface.BeaconState,
exits []*ethpb.SignedVoluntaryExit,
) (iface.BeaconState, error) {
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
return nil, errors.New("nil voluntary exit in block body")
@@ -73,59 +67,33 @@ func ProcessVoluntaryExits(
return beaconState, nil
}
// ProcessVoluntaryExitsNoVerifySignature processes all the voluntary exits in
// a block body, without verifying their BLS signatures.
// This function is here to satisfy fuzz tests.
func ProcessVoluntaryExitsNoVerifySignature(
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
exits := body.VoluntaryExits
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
return nil, errors.New("nil exit")
}
val, err := beaconState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)
if err != nil {
return nil, err
}
if err := verifyExitConditions(val, beaconState.Slot(), exit.Exit); err != nil {
return nil, err
}
// Validate that fork and genesis root are valid.
_, err = helpers.Domain(beaconState.Fork(), exit.Exit.Epoch, params.BeaconConfig().DomainVoluntaryExit, beaconState.GenesisValidatorRoot())
if err != nil {
return nil, err
}
beaconState, err = v.InitiateValidatorExit(beaconState, exit.Exit.ValidatorIndex)
if err != nil {
return nil, errors.Wrapf(err, "failed to process voluntary exit at index %d", idx)
}
}
return beaconState, nil
}
// VerifyExitAndSignature implements the spec defined validation for voluntary exits.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
func VerifyExitAndSignature(validator stateTrie.ReadOnlyValidator, currentSlot uint64, fork *pb.Fork, signed *ethpb.SignedVoluntaryExit, genesisRoot []byte) error {
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, voluntary_exit.validator_index)
func VerifyExitAndSignature(
validator iface.ReadOnlyValidator,
currentSlot types.Slot,
fork *pb.Fork,
signed *ethpb.SignedVoluntaryExit,
genesisRoot []byte,
) error {
if signed == nil || signed.Exit == nil {
return errors.New("nil exit")
}
@@ -148,20 +116,24 @@ func VerifyExitAndSignature(validator stateTrie.ReadOnlyValidator, currentSlot u
// verifyExitConditions implements the spec defined validation for voluntary exits(excluding signatures).
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
func verifyExitConditions(validator stateTrie.ReadOnlyValidator, currentSlot uint64, exit *ethpb.VoluntaryExit) error {
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, voluntary_exit.validator_index)
func verifyExitConditions(validator iface.ReadOnlyValidator, currentSlot types.Slot, exit *ethpb.VoluntaryExit) error {
currentEpoch := helpers.SlotToEpoch(currentSlot)
// Verify the validator is active.
if !helpers.IsActiveValidatorUsingTrie(validator, currentEpoch) {
@@ -178,9 +150,10 @@ func verifyExitConditions(validator stateTrie.ReadOnlyValidator, currentSlot uin
// Verify the validator has been active long enough.
if currentEpoch < validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod {
return fmt.Errorf(
"%s: %d epochs vs required %d epochs",
"%s: %d of %d epochs. Validator will be eligible for exit at epoch %d",
ValidatorCannotExitYetMsg,
currentEpoch,
currentEpoch-validator.ActivationEpoch(),
params.BeaconConfig().ShardCommitteePeriod,
validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod,
)
}

View File

@@ -4,11 +4,12 @@ import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -16,73 +17,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessVoluntaryExits_ValidatorNotActive(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 0,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "non-active validator cannot exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_InvalidExitEpoch(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 10,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 0,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "expected current epoch >= exit epoch"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
@@ -97,7 +31,7 @@ func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 10,
})
@@ -110,7 +44,7 @@ func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
}
want := "validator has not been active long enough to exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
assert.ErrorContains(t, want, err)
}
@@ -127,7 +61,7 @@ func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) {
ExitEpoch: 10,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 0,
})
@@ -140,7 +74,7 @@ func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) {
}
want := "validator with index 0 has already submitted an exit, which will take place at epoch: 10"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
assert.ErrorContains(t, want, err)
}
@@ -159,7 +93,7 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
ActivationEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := v1.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Fork: &pb.Fork{
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
@@ -168,7 +102,7 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
Slot: params.BeaconConfig().SlotsPerEpoch * 5,
})
require.NoError(t, err)
err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch))
err = state.SetSlot(state.Slot() + params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)))
require.NoError(t, err)
priv, err := bls.RandKey()
@@ -188,21 +122,11 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
},
}
stateCopy := state.Copy()
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b)
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
require.NoError(t, err, "Could not process exits")
newRegistry := newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch) {
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
}
// Check conformance with NoVerify Exit Method.
newState, err = blocks.ProcessVoluntaryExitsNoVerifySignature(stateCopy, b.Block.Body)
require.NoError(t, err, "Could not process exits")
newRegistry = newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)), newRegistry[0].ExitEpoch)
}
}

View File

@@ -1,9 +1,9 @@
// Package blocks contains block processing libraries according to
// the eth2spec.
// the Ethereum beacon chain spec.
package blocks
import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
)

View File

@@ -5,10 +5,11 @@ import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -19,35 +20,43 @@ import (
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
// # Verify that the slots match
// assert block.slot == state.slot
// # Verify that proposer index is the correct index
// # Verify that the block is newer than latest block header
// assert block.slot > state.latest_block_header.slot
// # Verify that proposer index is the correct index
// assert block.proposer_index == get_beacon_proposer_index(state)
// # Verify that the parent matches
// assert block.parent_root == hash_tree_root(state.latest_block_header)
// # Save current block as the new latest block
// # Cache current block as the new latest block
// state.latest_block_header = BeaconBlockHeader(
// slot=block.slot,
// proposer_index=block.proposer_index,
// parent_root=block.parent_root,
// # state_root: zeroed, overwritten in the next `process_slot` call
// state_root=Bytes32(), # Overwritten in the next process_slot call
// body_root=hash_tree_root(block.body),
// # signature is always zeroed
// )
//
// # Verify proposer is not slashed
// proposer = state.validators[get_beacon_proposer_index(state)]
// proposer = state.validators[block.proposer_index]
// assert not proposer.slashed
// # Verify proposer signature
// assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
func ProcessBlockHeader(
_ context.Context,
beaconState *stateTrie.BeaconState,
block *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
beaconState, err := ProcessBlockHeaderNoVerify(beaconState, block.Block)
beaconState iface.BeaconState,
block interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(block); err != nil {
return nil, err
}
bodyRoot, err := block.Block().Body().HashTreeRoot()
if err != nil {
return nil, err
}
beaconState, err = ProcessBlockHeaderNoVerify(beaconState, block.Block().Slot(), block.Block().ProposerIndex(), block.Block().ParentRoot(), bodyRoot[:])
if err != nil {
return nil, err
}
// Verify proposer signature.
if err := VerifyBlockSignature(beaconState, block); err != nil {
if err := VerifyBlockSignature(beaconState, block.Block().ProposerIndex(), block.Signature(), block.Block().HashTreeRoot); err != nil {
return nil, err
}
@@ -64,51 +73,52 @@ func ProcessBlockHeader(
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
// # Verify that the slots match
// assert block.slot == state.slot
// # Verify that proposer index is the correct index
// # Verify that the block is newer than latest block header
// assert block.slot > state.latest_block_header.slot
// # Verify that proposer index is the correct index
// assert block.proposer_index == get_beacon_proposer_index(state)
// # Verify that the parent matches
// assert block.parent_root == hash_tree_root(state.latest_block_header)
// # Save current block as the new latest block
// # Cache current block as the new latest block
// state.latest_block_header = BeaconBlockHeader(
// slot=block.slot,
// proposer_index=block.proposer_index,
// parent_root=block.parent_root,
// # state_root: zeroed, overwritten in the next `process_slot` call
// state_root=Bytes32(), # Overwritten in the next process_slot call
// body_root=hash_tree_root(block.body),
// # signature is always zeroed
// )
//
// # Verify proposer is not slashed
// proposer = state.validators[get_beacon_proposer_index(state)]
// proposer = state.validators[block.proposer_index]
// assert not proposer.slashed
func ProcessBlockHeaderNoVerify(
beaconState *stateTrie.BeaconState,
block *ethpb.BeaconBlock,
) (*stateTrie.BeaconState, error) {
if block == nil {
return nil, errors.New("nil block")
}
if beaconState.Slot() != block.Slot {
return nil, fmt.Errorf("state slot: %d is different than block slot: %d", beaconState.Slot(), block.Slot)
beaconState iface.BeaconState,
slot types.Slot, proposerIndex types.ValidatorIndex,
parentRoot, bodyRoot []byte,
) (iface.BeaconState, error) {
if beaconState.Slot() != slot {
return nil, fmt.Errorf("state slot: %d is different than block slot: %d", beaconState.Slot(), slot)
}
idx, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, err
}
if block.ProposerIndex != idx {
return nil, fmt.Errorf("proposer index: %d is different than calculated: %d", block.ProposerIndex, idx)
if proposerIndex != idx {
return nil, fmt.Errorf("proposer index: %d is different than calculated: %d", proposerIndex, idx)
}
parentHeader := beaconState.LatestBlockHeader()
if parentHeader.Slot >= block.Slot {
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", block.Slot, parentHeader.Slot)
if parentHeader.Slot >= slot {
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", slot, parentHeader.Slot)
}
parentRoot, err := parentHeader.HashTreeRoot()
parentHeaderRoot, err := parentHeader.HashTreeRoot()
if err != nil {
return nil, err
}
if !bytes.Equal(block.ParentRoot, parentRoot[:]) {
if !bytes.Equal(parentRoot, parentHeaderRoot[:]) {
return nil, fmt.Errorf(
"parent root %#x does not match the latest block header signing root in state %#x",
block.ParentRoot, parentRoot)
parentRoot, parentHeaderRoot[:])
}
proposer, err := beaconState.ValidatorAtIndexReadOnly(idx)
@@ -119,16 +129,12 @@ func ProcessBlockHeaderNoVerify(
return nil, fmt.Errorf("proposer at index %d was previously slashed", idx)
}
bodyRoot, err := block.Body.HashTreeRoot()
if err != nil {
return nil, err
}
if err := beaconState.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: block.Slot,
ProposerIndex: block.ProposerIndex,
ParentRoot: block.ParentRoot,
Slot: slot,
ProposerIndex: proposerIndex,
ParentRoot: parentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
BodyRoot: bodyRoot[:],
BodyRoot: bodyRoot,
}); err != nil {
return nil, err
}

View File

@@ -5,18 +5,19 @@ import (
"io/ioutil"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/sirupsen/logrus"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
func init() {
@@ -34,15 +35,13 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetSlot(10))
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: 10, // Must be less than block.Slot
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
require.NoError(t, state.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
Slot: 10, // Must be less than block.Slot
})))
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
@@ -67,19 +66,16 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, wrapper.WrappedPhase0SignedBeaconBlock(block))
assert.ErrorContains(t, "block.Slot 10 must be greater than state.LatestBlockHeader.Slot 10", err)
}
func TestProcessBlockHeader_WrongProposerSig(t *testing.T) {
testutil.ResetCache()
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
require.NoError(t, beaconState.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
require.NoError(t, beaconState.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
})))
require.NoError(t, beaconState.SetSlot(10))
lbhdr, err := beaconState.LatestBlockHeader().HashTreeRoot()
@@ -96,7 +92,7 @@ func TestProcessBlockHeader_WrongProposerSig(t *testing.T) {
block.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx+1])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, block)
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
want := "signature did not verify"
assert.ErrorContains(t, want, err)
}
@@ -112,16 +108,13 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
require.NoError(t, state.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
ProposerIndex: 0,
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
require.NoError(t, state.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
})))
lbhsr, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
@@ -129,21 +122,19 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
sszBytes := p2ptypes.SSZBytes("hello")
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, &sszBytes, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[5896].PublicKey = priv.PublicKey().Marshal()
block := &ethpb.SignedBeaconBlock{
block := testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 1,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
Slot: 1,
ParentRoot: lbhsr[:],
},
Signature: blockSig,
}
})
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, wrapper.WrappedPhase0SignedBeaconBlock(block))
want := "is different than block slot"
assert.ErrorContains(t, want, err)
}
@@ -159,7 +150,8 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
bh := state.LatestBlockHeader()
@@ -168,7 +160,8 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
currentEpoch := helpers.CurrentEpoch(state)
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
sszBytes := p2ptypes.SSZBytes("hello")
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, &sszBytes, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[5896].PublicKey = priv.PublicKey().Marshal()
pID, err := helpers.BeaconProposerIndex(state)
@@ -180,7 +173,7 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
block.Block.ParentRoot = bytesutil.PadTo([]byte{'A'}, 32)
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, wrapper.WrappedPhase0SignedBeaconBlock(block))
want := "does not match"
assert.ErrorContains(t, want, err)
}
@@ -196,7 +189,8 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
bh := state.LatestBlockHeader()
@@ -207,7 +201,8 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
currentEpoch := helpers.CurrentEpoch(state)
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
sszBytes := p2ptypes.SSZBytes("hello")
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, &sszBytes, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[12683].PublicKey = priv.PublicKey().Marshal()
@@ -220,7 +215,7 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
block.Block.ParentRoot = parentRoot[:]
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, wrapper.WrappedPhase0SignedBeaconBlock(block))
want := "was previously slashed"
assert.ErrorContains(t, want, err)
}
@@ -236,16 +231,13 @@ func TestProcessBlockHeader_OK(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
require.NoError(t, state.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
ProposerIndex: 0,
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
require.NoError(t, state.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
})))
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
@@ -272,7 +264,7 @@ func TestProcessBlockHeader_OK(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
newState, err := blocks.ProcessBlockHeader(context.Background(), state, block)
newState, err := blocks.ProcessBlockHeader(context.Background(), state, wrapper.WrappedPhase0SignedBeaconBlock(block))
require.NoError(t, err, "Failed to process block header got")
var zeroHash [32]byte
nsh := newState.LatestBlockHeader()
@@ -297,16 +289,14 @@ func TestBlockSignatureSet_OK(t *testing.T) {
}
}
state := testutil.NewBeaconState()
state, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
require.NoError(t, state.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
require.NoError(t, state.SetLatestBlockHeader(testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
Slot: 9,
ProposerIndex: 0,
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
})))
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
@@ -329,7 +319,7 @@ func TestBlockSignatureSet_OK(t *testing.T) {
validators[proposerIdx].PublicKey = priv.PublicKey().Marshal()
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
set, err := blocks.BlockSignatureSet(state, block)
set, err := blocks.BlockSignatureSet(state, block.Block.ProposerIndex, block.Signature, block.Block.HashTreeRoot)
require.NoError(t, err)
verified, err := set.Verify()

View File

@@ -4,59 +4,57 @@ import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"google.golang.org/protobuf/proto"
)
type slashValidatorFunc func(iface.BeaconState, types.ValidatorIndex) (iface.BeaconState, error)
// ProcessProposerSlashings is one of the operations performed
// on each processed beacon block to slash proposers based on
// slashing conditions if any slashable events occurred.
//
// Spec pseudocode definition:
// def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSlashing) -> None:
// """
// Process ``ProposerSlashing`` operation.
// """
// proposer = state.validator_registry[proposer_slashing.proposer_index]
// # Verify slots match
// assert proposer_slashing.header_1.slot == proposer_slashing.header_2.slot
// # But the headers are different
// assert proposer_slashing.header_1 != proposer_slashing.header_2
// # Check proposer is slashable
// assert is_slashable_validator(proposer, get_current_epoch(state))
// # Signatures are valid
// for header in (proposer_slashing.header_1, proposer_slashing.header_2):
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
// assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)
// header_1 = proposer_slashing.signed_header_1.message
// header_2 = proposer_slashing.signed_header_2.message
//
// slash_validator(state, proposer_slashing.proposer_index)
// # Verify header slots match
// assert header_1.slot == header_2.slot
// # Verify header proposer indices match
// assert header_1.proposer_index == header_2.proposer_index
// # Verify the headers are different
// assert header_1 != header_2
// # Verify the proposer is slashable
// proposer = state.validators[header_1.proposer_index]
// assert is_slashable_validator(proposer, get_current_epoch(state))
// # Verify signatures
// for signed_header in (proposer_slashing.signed_header_1, proposer_slashing.signed_header_2):
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(signed_header.message.slot))
// signing_root = compute_signing_root(signed_header.message, domain)
// assert bls.Verify(proposer.pubkey, signing_root, signed_header.signature)
//
// slash_validator(state, header_1.proposer_index)
func ProcessProposerSlashings(
_ context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
beaconState iface.BeaconState,
slashings []*ethpb.ProposerSlashing,
slashFunc slashValidatorFunc,
) (iface.BeaconState, error) {
var err error
for idx, slashing := range body.ProposerSlashings {
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)
}
beaconState, err = v.SlashValidator(
beaconState, slashing.Header_1.Header.ProposerIndex,
)
beaconState, err = slashFunc(beaconState, slashing.Header_1.Header.ProposerIndex)
if err != nil {
return nil, errors.Wrapf(err, "could not slash proposer index %d", slashing.Header_1.Header.ProposerIndex)
}
@@ -66,7 +64,7 @@ func ProcessProposerSlashings(
// VerifyProposerSlashing verifies that the data provided from slashing is valid.
func VerifyProposerSlashing(
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
slashing *ethpb.ProposerSlashing,
) error {
if slashing.Header_1 == nil || slashing.Header_1.Header == nil || slashing.Header_2 == nil || slashing.Header_2.Header == nil {

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