Compare commits

...

454 Commits

Author SHA1 Message Date
Nishant Das
4bc7cb6959 exit better (#7697) 2020-11-02 13:25:44 +08:00
Victor Farazdagi
3584bcba8e Fix param naming in BestNonFinalized (#7693) 2020-11-01 00:03:44 +00:00
Victor Farazdagi
926d3b9b34 Init-sync: more tests + minor refactoring (#7692)
* cherry-pick commits

* re-arrange calls
2020-10-31 21:33:57 +00:00
terence tsao
817c16a2f4 Use a short cut in migration step (#7686)
* Don't generate state if it's already in DB

* Use proper missing root

* Update logic for clarity
2020-10-31 19:01:05 +00:00
terence tsao
92b6e0b6af Add and use HasStateInCache (#7691) 2020-10-31 11:38:01 -07:00
Raul Jordan
b3155a04f5 Revert "Revert "Add In Progress Checker For Checkpoint Cache"" (#7690)
This reverts commit 46c04b98d9.
2020-10-31 15:59:50 +00:00
Nishant Das
df762bbfee cleaner logging (#7689) 2020-10-31 19:10:08 +08:00
terence tsao
f79b168ab2 Update to correct odering (#7688) 2020-10-31 10:08:22 +08:00
Nishant Das
211d9bc0b9 Update BLST And Herumi (#7632)
* fix build from source

* clean up

* update again

* change everything

* workaround for now

* fix versioning

* all passing now

* fix build issues

* clean up

* revert use of MulVerify

* gaz

* stub

* Apply suggestions from code review

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

* fix all

* fix test

* todo

* fix stub

* revert back

* make deep source happy

* Update shared/bls/herumi/public_key.go

* Update shared/bls/blst/signature.go

* Update shared/bls/blst/signature_test.go

* imports

* move iface to common, export errors

* rm iface build

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-10-30 19:06:33 +00:00
terence tsao
386bfdd6eb Remove deprecated headstate method in DB (#7680)
* Remove head state in DB

* Clean up tests

* Fix pow tests

* Add stateGen to pow service
2020-10-30 15:11:08 +00:00
Raul Jordan
ddc8dc36f8 remove use of recover (#7683)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-10-30 14:40:26 +08:00
Preston Van Loon
99f15943a8 Fuzz: sigp/beaconfuzz#78 (#7684)
* Add failing test to verify https://github.com/sigp/beacon-fuzz/issues/78

* revert beacon-chain/core/blocks/spectest/attestation_test.go

* Describe bug in comments, fix bug

* 1
2020-10-30 02:06:53 +00:00
Raul Jordan
581bed2017 Load in JSON Validators for Genesis State Generation (#7643)
* load in genesis state from JSON validators

* completed feature with tests

* bazel change

* fix docker image

* deep source
2020-10-29 22:37:16 +00:00
Raul Jordan
2d4bfbbe31 Web UI Security Improvements (#7676)
* remove delete accounts

* check if user has not yet signed up
2020-10-29 16:38:47 -05:00
terence tsao
fb2dfec1f4 Use state by root to get finalized state (#7677) 2020-10-29 14:04:06 -05:00
Nishant Das
2e4dee5aeb Stategen Bug Fixes (#7674)
* bug fixes

* fix

* terence's review

* Make comments more explicit

* Update variable names

* Update tests

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-10-29 16:14:57 +00:00
Nishant Das
46c04b98d9 Revert "Add In Progress Checker For Checkpoint Cache" (#7672)
This reverts commit 37bf6617c0.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-29 14:35:30 +00:00
terence tsao
301499d134 Fill in blocks to fork choice store during init (#7665)
* Fill in blocks to fork choice store during init

* Use format option

* Use format option

* Use correct head block. Thanks Nishant

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-29 05:27:30 +00:00
Victor Farazdagi
4fc0a50569 Turn init-sync FSM logs to trace level (#7670)
* trace

* go fmt

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-29 04:55:07 +00:00
Preston Van Loon
c1c0b53c25 validateCommitteeIndexBeaconAttestation: Reorder boolean logic to reduce db calls (#7671)
* reorder boolean logic to shortcut

* same issue, in another place

* refactor for the greater good
2020-10-29 04:14:16 +00:00
Nishant Das
37bf6617c0 Add In Progress Checker For Checkpoint Cache (#7659)
* add inprogress checker

* fix test

* fix

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-10-29 01:21:49 +00:00
Preston Van Loon
149d3b84fa Check attestation target checkpoint epoch matches attestation slot (#7667)
* Check attestation target checkpoint is within current or previous epoch

* reject bad att where slot does not match target

* Add test, reduce redundant check
2020-10-29 00:52:18 +00:00
Preston Van Loon
5092093389 Revert "Remove redundant checks in processAttestation" (#7666)
This reverts commit 3b34954e75.
2020-10-28 22:46:26 +00:00
terence tsao
3b34954e75 Remove continue checks (#7663) 2020-10-28 13:04:28 -07:00
Preston Van Loon
ec5e59e212 remove unused and untested method (#7662)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-28 12:03:30 -07:00
Shay Zluf
7d1a1643ee Add validator datadir use (#7660)
* fix empty db prompt

* wording

* fix merge

* prompt only on datadir use

* remove move datadir function

* remove flag

* remove prompt text

* remove added prompt function

* gaz
2020-10-28 12:09:44 -05:00
Preston Van Loon
5f80754013 Revert "Remove Top Jaeger Span Offenders" (#7657)
This reverts commit ec8eab21ae.

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-28 06:07:14 +00:00
Raul Jordan
d9e4084d6d Remove Lock Contention in getAttPreState (#7656)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-28 05:42:54 +00:00
Raul Jordan
ec8eab21ae Remove Top Jaeger Span Offenders (#7655) 2020-10-28 05:14:54 +00:00
terence tsao
0cbd8bc03d Use root + slot for skip slot cache key (#7654)
* Update skip slot cache's key

* Add tests

* Refactor into its own function

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-28 03:09:05 +00:00
Victor Farazdagi
e57770bd0a Fix slasher ReadOnlyDatabase.BlockHeaders parameter names (#7652)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-28 02:36:02 +00:00
Raul Jordan
8c2fff3a75 Allow for 25th Word Passphrases in Mnemonics (#7645)
* advanced functionality, enable 25th word mnemonic passphrase

* 25th word passphrase

* add test

* added test to ensure differences when using the mnemonic 25th word

* better message

* passing tests

* fix up logic
2020-10-27 20:51:29 +00:00
Nishant Das
4f5726b3af Initialize State Correctly In Powchain (#7648)
* fix bug

* Update beacon-chain/powchain/service.go

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

* return error

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-27 17:50:46 +00:00
Preston Van Loon
424488bf8a Deprecate db.HeadState (#7653)
* Deprecate db.HeadState

* Deprecate db.HeadState
2020-10-27 16:25:52 +00:00
Radosław Kapka
21c5ba8ed8 display that all validators are exited (#7651) 2020-10-27 09:29:58 -05:00
Victor Farazdagi
dbbbc7586f Remove redundant attribute in validator test (#7649)
* remove redundant attribute in validator test

* remove other attribs
2020-10-27 12:15:35 +00:00
Preston Van Loon
fcbb168c76 Code health: review map usage (#7635)
* remove unused cache states map

* correct typo

* Remove unused array

* Add lock around deposits cache chainstart pubkeys

* Copy attestation before grabbing lock. This may reduce lock contention time as other callers wanting the lock do not need to wait as long for the lock to become available.

* Copy attestation before grabbing lock. This may reduce lock contention time as other callers wanting the lock do not need to wait as long for the lock to become available.

* Set capacity to 1 since it is known that the slice will be 1 after insertion

* require validatorSlashingPreconditionCheck caller to hold lock

* Add lock for voluntary exits pool HasBeenIncluded

* Require rate limiter retrieveCollector to hold lock

* Add lock requirement assertions in sync

* Remove unused struct

* remove ClearCachedStates API

* field initSyncState is unused

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-26 21:17:07 +00:00
Nishant Das
f1bce1001d Restrict Proposer Lookup to the Current Epoch (#7542)
* checkpoint

* add test

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

* preston's review

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-26 13:40:38 -07:00
terence tsao
ec77196197 Remove checkpoint info cache and usages (#7642)
* Remove checkpoint info cache and usages

* Gazelle
2020-10-26 14:09:19 -05:00
Raul Jordan
a468a12ef0 Allow Specifying Output Directory When Creating DB Backups (#7630)
* move flags

* backup db output dir flag

* fix build

* fix up broken backup test

* Radek's feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-26 18:20:54 +00:00
Radosław Kapka
b0dff891fc Invert enable-eth1data-majority-vote (#7362)
* make flag opt-out

* fix flags

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-26 17:36:47 +00:00
Raul Jordan
687251fedc keep asking for account pass if fails decrypt (#7631) 2020-10-26 17:56:57 +01:00
Alon Muroch
a04b7c2e4f Slasher highest source target (#7604)
* WIP - slasher highest attestation start

* fixed previous

* highest source and target

* highest attestation cache

* cleanup

* persist + fixes

* PR fixes and cleanup

* slashing proto

* highest att. api

* cleanup + tests

* increased highest att. cache to 300K

* removed highest att. api (for a separate PR)

* fixed linting

* bazel build fix

* highest att. kv test

* slasher highest att. test + purge + fix on eviction persist performance

* cleanup + linting

* linting + test fixes

* bazel gazelle run

* PR fixes

* run goimports

* go mod tidy

* ineffectual assignment fix

* run gazelle

* bazel gazelle run

* test fixes

* linter fix

* Apply suggestions from code review

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

* goimports run

* cache tests

* A bunch of small fixes

* gazelle fix + gofmt

* merge fixes

* kv ordering fix

* small typos and text fixes

* capital letter fix

Co-authored-by: Shay Zluf <thezluf@gmail.com>
2020-10-26 14:15:42 +02:00
Victor Farazdagi
e6d688f6d5 Init-sync: re-arrange tests (#7641)
* move tests

* formatting

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-26 08:54:06 +00:00
Victor Farazdagi
8a3b75e9e3 Update init-sync FSM (#7640)
* update fsm

* more tests
2020-10-26 05:26:35 +00:00
terence tsao
a73c539fab Forkchoice: update read only lock to regular lock (#7633) 2020-10-24 16:35:18 +00:00
Nishant Das
92efe64b8a Fix Gossip Message ID (#7624)
* fix snappy errors

* gaz

* Update beacon-chain/p2p/pubsub.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-24 03:38:05 +00:00
Raul Jordan
b1c047b9ee Prevent Panics in Field Trie Helpers (#7613)
* add tests to prevent panics

* if > 0

* fix typ
2020-10-23 21:41:45 +00:00
Nishant Das
ff50ea2e0d Better Logging When Using Head Sync (#7626)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-23 21:00:53 +00:00
terence tsao
ebb3fa71f1 VerifyFinalizedConsistency - return early when canonical (#7628)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-23 19:02:20 +00:00
Preston Van Loon
9ea69a070e Fix attestation broadcast recovery metric (#7629) 2020-10-23 18:41:17 +00:00
Raul Jordan
c59edb3358 Revert "Use validator protection datadir" (#7627)
This reverts commit ab76bdad15.
2020-10-23 17:19:38 +00:00
Radosław Kapka
7e2112b4ba Fix panic issues on beacon node shutdown (#7625)
* allow service cleanup on node shutdown

* revert error to fatal

* remove unused struct field
2020-10-23 12:43:48 +00:00
bidlocode
cdbbf66027 Fix pregenesis countdown msg wording (#7477)
* fix wording

* fix gofmt

* fix msg

* gofmt

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-10-23 05:21:52 +00:00
Victor Farazdagi
e5e51e66e1 Handle voting ties in BestFinalized() (#7622) 2020-10-23 04:43:35 +00:00
Nishant Das
6eb022ffa1 Clean Up Block Retrieval Methods (#7593)
* fix and add tests

* return for 0

* add test case

* fix

* fix fail

* add comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-23 04:23:15 +00:00
Nishant Das
e776eb5409 Fix Powchain Error In Startup (#7621)
* fix error

* add test case
2020-10-23 03:57:19 +00:00
Victor Farazdagi
6a2bb65fe2 Fix BestFinalized method (#7619)
* turn tests to use testing vector

* add regression test case

* complete tests
2020-10-23 02:49:42 +00:00
Preston Van Loon
ecc25d2b8c Release and remove feature flag --enable-att-broadcast-discovery-attempts (#7610)
* Release and remove feature flag --enable-att-broadcast-discovery-attempts

* fix test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-23 01:53:50 +00:00
terence tsao
e07a12e6b7 Move IsCanonical implementation to forkchoice package (#7602)
* Move IsCanonical implementation to forkchoice pkg

* Remove debug print log

* Add tests

* Fixed current tests

* Fixed a test

* Fixed a test

* Add tests for cov
2020-10-23 01:32:13 +00:00
terence tsao
840ffc84ac Save state to DB during long non-finality (#7597)
* Starting saving state during hot

* Add a log

* Add helpers to turn on/off mode

* Add locks

* Add missing return

* Clean up

* Add logic to migration to handle db roots

* Add tests for on and off

* Add more tests

* Add test for migrate

* @prestonvanloon's feedback

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-23 00:35:30 +00:00
Raul Jordan
ca081e8639 Fatal If No TLS Found in RPC Service (#7614)
* fatal if no tls found rpc

* tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 23:58:53 +00:00
Raul Jordan
e54ac48f9d Deep Source Security Issues (#7617)
* deep source issues

* fix broken build

* fix beacon chain build

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-22 23:31:52 +00:00
Raul Jordan
075f1458b4 Do Not Recommend --ssl-no-revoke When Downloading Prysm Scripts (#7618)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 22:25:22 +00:00
Raul Jordan
be6481e178 Amend Cross Compile README (#7615)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 21:41:46 +00:00
Shay Zluf
ab76bdad15 Use validator protection datadir (#7355)
* Add validator protection db flag

* fix nil handling

* reuse datadir

* add datadir default config

* Add handling for moving account dir datafile to new set dir

* naming conditionals

* add tests

* fix test

* fix logic to default to wallet dir

* raul feedback

* nishant feedback

* gaz

* revert site_data changes

* fix formatting

* fix formatting

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-22 21:05:08 +00:00
Raul Jordan
e7723c4d1f Remove Deprecated Participation Metrics (#7616)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 20:14:58 +00:00
Raul Jordan
a688b9e030 Miscellaneous Docs Improvements (#7606)
* misc docs fixes

* revert readme

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 19:45:31 +00:00
Raul Jordan
ff15621fe1 Fix Nil Pointer in RPC List Peers (#7612)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 18:48:58 +00:00
Raul Jordan
4a78071e41 Explicit Password Requirements (#7607)
* explicit password requirements

* explicit reqs

* explicit reqs

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 18:02:30 +00:00
Raul Jordan
113b2cd6cf Clarify No Wallet Found Error Messages (#7609)
* clarify no wallet found error messages

* extract error

* fix tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 17:31:03 +00:00
Raul Jordan
13af8a7a37 Remove Unusued Base Parameter in SubscribeWithBase (#7608)
* remove base in sub with base param

* refactor subscribeWithBase signature
2020-10-22 16:56:24 +00:00
Nishant Das
7131cd991c Ignore PreGenesis Messages Instead Of Rejecting Them (#7550)
* ignorePreGenesisMessages

* fix test + handelaar's review

* fix issues

* change back

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 15:43:35 +00:00
Radosław Kapka
17a08a75ea Move voluntary exit logging to accounts_exit (#7603)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-22 15:01:11 +00:00
Nishant Das
ddbece5988 Fix Range Request Responses (#7531)
* checkpoint

* fix tests

* fix all tests

* imports

* gazelle

* reviews

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-22 09:33:01 -05:00
bidlocode
ff658ba641 Fix w3endpoint file relative path (#7557)
* add expandpath

* fix error description

* fix bazel & deepsource

* fix

* fix gofmt

* fix refactor

* add tests

* gofmt

* fix

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-22 05:53:03 +00:00
Victor Farazdagi
483f7f8177 Fix InitWithReset - rely on previously updated flags (#7598)
* Fix initWithReset to use previously set configuration

* further cleanup

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 05:20:56 +00:00
Preston Van Loon
b4c1c1db9b Add lighthouse p2p Good Bye codes (#7601)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-22 00:35:10 +00:00
Preston Van Loon
70d923cf85 Change log level from panicf to errorf so that all services can be shutdown (#7600) 2020-10-21 23:41:01 +00:00
Raul Jordan
e4e8dd4838 Fix Web UI Integration With Prysm Beta (#7591)
* fix change password endpoint

* attempt same port as gateway

* update site to latest release

* final fixes

* rem gorilla mux

* gaz fix

* gaz fix

* fmt

* fix build

* fix flags
2020-10-21 17:32:00 -05:00
Daniel Pittman
553492e6e9 Update TERMS_OF_SERVICE.md (#7590)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-21 20:34:40 +00:00
terence tsao
9554ad3221 Exit early if there's no validator slashing (#7587)
* Add a logic to exit early if there's no slashing

* Apply the same idea to final update

* Add conditions to satisfy fuzz

* Revert final updates changes

* Add comments

* Add a new test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-21 19:12:39 +00:00
Raul Jordan
d2f7240255 Context Cancelation Handling for Hot States (#7596)
* attempt deadline for state info

* cancel check
2020-10-21 17:06:48 +00:00
terence tsao
42b7a37281 Add span for AncestorRoot (#7595)
* Add spans for AncestorRoot

* Add span for ancestor by DB

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-21 16:26:19 +00:00
Potuz
9a6a70e804 Add journald to log-format help (#7572)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-21 15:47:31 +00:00
bidlocode
9bd3cede23 Checking ToS cli flag in subcommands (#7588)
* check tos in subcmds

* fix
2020-10-21 10:13:46 -05:00
terence tsao
544dac298a Check ListValidatorBalances response length (#7583)
* Check length

* Add regression test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-20 20:45:38 +00:00
Raul Jordan
78ca8c9265 Add Accept Terms of Use Flags to Accounts Commands (#7584) 2020-10-20 20:12:49 +00:00
terence tsao
a5ce6db38e Update participation metrics (#7582)
* Update participation metrics

* Add unhappy tests
2020-10-20 14:14:24 -05:00
Victor Farazdagi
0b53a89d00 More verbose output on init-sync (#7578)
* more verbose output on init-sync

* log slot

* no error stack

* remove redundant data

* less verbose
2020-10-20 14:59:38 +00:00
Raul Jordan
fdef581e02 Invalidate JWT in Backend Logout (#7574)
* logout by invalidating in backend

* gaz

* regen pb.go

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-20 11:41:19 +00:00
Shay Zluf
7c5ee0a806 prune slasher attestations (#7335)
* prune slasher attestations

* remove unused code

* gaz

* remove unused methods from interface

* fix banchmark

* fix banchmark

* go.mod tidy

* preston feedback

* add test

* goimports

* fix test

* rm

* working version

* revert changes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-20 14:09:01 +03:00
Nishant Das
81b553a00a Fix Overflow Bugs Introduced (#7579) 2020-10-20 06:18:03 +00:00
Raul Jordan
816eb94adf Validate JWT Signing Type in RPC (#7576)
* validate jwt signing type

* lint

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-20 05:37:12 +00:00
Radosław Kapka
ec0af98a9e Cache ETH1 headers on startup for eth1data voting (#7541)
* initial commit

* branch cleanup

* gzl

* underscore for unused parameteres

* caching implemented

* BlockExistsWithCache - tests

* add missing method to mock POWChain

* add missing method to faulty mock POWChain

* fix failing test

* add underflow checks

* change warning to error

* use helper to calculate end block

Co-authored-by: nisdas <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>
2020-10-20 05:10:27 +00:00
Raul Jordan
a39db494eb Remove Accounts Backup Validator RPC Functionality (#7575)
* remove accounts backup via RPC

* fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-20 04:33:22 +00:00
Nishant Das
05678b6724 Update to Discovery V5.1 (#7302)
* discoveryV5.1

* add seed node

* fix up

* checkpoint

* Add workaround for discv5.1 signature curve. Add discv5.1 catdog ENR

* remove dead code

* Add another catdog

* Fix bootnode

* fix docker img

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-20 04:05:48 +00:00
Raul Jordan
bec91d348e Use Password Specific to Web UI Instead of Wallet Password (#7569)
* use password specific to web UI

* fix up a few more tests

* tests passing

* gaz

* fix fmt
2020-10-20 02:26:31 +00:00
Raul Jordan
1bc86d2658 Remove Account Creation Privilege For Imported Keymanager (#7555)
* rem create

* remove create account privilege for nonhd wallets

* fix bazel

* radek feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-20 01:22:36 +00:00
terence tsao
9db6c0042b Add LMD FFG consistency check to aggregated attestation (#7573)
* Add lmd and ffg check

* Update tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 23:19:44 +00:00
terence tsao
3d70d757a1 Add checking for finalized consistency (#7568)
* Add checking for finalized consistency

* Add tests

* @prestonvanloon's feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 21:52:18 +00:00
terence tsao
e25cd08049 Rename unsafe-sync to head-sync (#7570)
* Rename unsafe-sync to head-sync

* Update comments

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 20:03:31 +00:00
Radosław Kapka
dccf0992e5 Verify eth1data vote in E2E (#7551)
* add majority vote to e2e

* extract policies to a separate package

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 19:35:34 +00:00
Raul Jordan
f6ed3f141a Remove Default Wallet Endpoint (#7571)
* remove default endpoint

* remove from required auth endpoints

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 19:05:51 +00:00
Radosław Kapka
88b2a4c905 Invert enable-pruning-deposit-proofs (#7565)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 18:22:44 +00:00
Preston Van Loon
ab40a112c5 Print the underlying error when attestation fails to get pre state (#7567)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-19 17:03:27 +00:00
Nishant Das
329fbff814 Use StateRoot as Key for Cache (#7540)
* checkpoint

* review

* comment

* fix bad bug

* fix up
2020-10-19 09:13:47 -07:00
Nishant Das
f31d40cf34 Fix Unsafe Sync Flag (#7563)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-18 22:28:44 +00:00
Nishant Das
49909ce351 Remove checkpoint cache flag from --dev (#7560)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-10-18 21:56:55 +00:00
bidlocode
53ab1dff6d Make ToS non-interactive err message more descriptive (#7562)
* add descriptive err msg

* Update shared/tos/tos.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-18 17:08:57 +00:00
Nishant Das
b502876e98 Fix Mismatched BlockRoots In State Replay (#7559)
* fix mismatched roots

* alternate approach

* preston's review

* comment
2020-10-18 09:39:27 -07:00
Radosław Kapka
f474c4b1c5 Don't show stack trace for certain voluntary exit failure scenarios (#7554)
* handle some scenarios more gracefully

* allow accounts access to core/blocks package
2020-10-17 10:08:58 +00:00
bidlocode
78fd3b8a87 Fix import cannot find the file on windows (#7556) 2020-10-17 06:00:13 +00:00
Raul Jordan
7e44d1eec7 Rename Direct Keymanager to Imported (#7549)
* rename direct to imported

* km

* fix more refs

* rename all instances appropriately

* rename instances of nonhd
2020-10-16 13:45:14 -05:00
bidlocode
9a0d579607 Fix voluntary exit --tls-cert flag (#7547)
* fix getting flag values from ctx

* fix

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2020-10-16 14:27:01 +00:00
Preston Van Loon
07e7e030d9 Update PubSub and include topic filter (#7496)
* Update pubsub and fix topicIDs

* WIP filter

* Add suggested code from @bidlocode

* add tests and fix bugs

* more tests

* Wait until state initialized to accept pubsub filtering

* rename for clarity and clarify comment

* fix test builds

* Autofix issues in 2 files

Resolved issues in the following files via DeepSource Autofix:
1. beacon-chain/p2p/pubsub_filter.go
2. beacon-chain/p2p/pubsub_filter_test.go

* @nisdas pr feedback

* pr feedback and fuzz fix

* Update beacon-chain/p2p/pubsub_filter.go

* Must have protocol suffix

* Must have protocol suffix

* gofmt

* rm test, fix panic

* Fix tests

* Add isInitialized check

* Add a few more tests for better coverage

* cache fork digest, make pubsub filter part of the p2p service

* rename service

* gofmt

* Add comment

* fix

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-16 07:05:40 +00:00
Raul Jordan
a81c863ddb Rename Accounts-V2 to Accounts (#7545)
* rename accounts v2

* rename keymanager and fix imports

* rename accounts-v2 instances

* imports

* build

* build fix

* deepsource

* fix up broken aliases

* imports

* gaz

* Update validator/accounts/accounts_import_test.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>

* fmt

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
2020-10-15 22:31:52 +00:00
bidlocode
7aaefd123e Accept ToS: fix (#7539)
* fix create datadir on fresh run

* add test

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-15 21:30:38 +00:00
Raul Jordan
7abc1feaf5 Update Ethdo Keystore Deps (#7537)
* include old crypto code

* update gomod

* delete new util

* add versioning for determining derivation strategy

* add versioning

* tidy and gazelle viz

* fix tests

* fix broken

* workspace fix

* fix workspace

* revert

* fix test

* derived test fix
2020-10-15 15:33:10 -05:00
Shay Zluf
acf201428e Use new proposal protection format (#7518)
* Use new proposal protection format

* Update comments

* Split and merge with new db

* fix tests

* fix test

* optimize domain

* fix validation

* fix validation

* check import error

* fix e2e

* fix old propose tests add ign block test

* constant secret key

* static test for signing

* test domain

* fix testsplit

* gaz

* gaz

* tidy

* raul feedback

* fix tests

* tidy

* added info log for the migration

* gaz

* Update validator/client/propose_protect.go

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

* nishant feedback

* import fix

* fix

* remove propose protection flag

* fix block sign test

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-15 19:35:31 +00:00
Ivan Martinez
daf0b51361 Eth2 API: Implement block endpoints (#7433)
* Start Beacon API outline

* Rename to v1

* Add impl

* Change to outline

* Add comments

* Remove unneeded items

* Fix linting

* tidy

* Fix visibility

* go.sum

* Fix deps

* Tidy

* Implement blocks API endpoints

* Add check for interface type and fix pointers

* Fix pointer name

* gaz

* Fix comments

* Fix imports

* Fix analysis

* Add more coverage

* Add coverage and fix errors

* Fix head test

* Fix test remove println

* Fix error text and cleanup

* Change tests to TDD

* Add tests for finalized

* Fix att test

* Fix analysis

* Fix go mo d

* Fix proto

* fix go mod

* Extend testing

* Fix tests

* Move migration to package and test block atts

* Fix migration

* Gaz

* Check for block canonical before returning

* Fix text

* Gaz

* Fix tests

* Fix tests

* Fix canonical

* Fix test again

* Fix tests

* Remove unneeded comment

* Plug in RPC service

* Fix err msg
2020-10-15 18:00:49 +00:00
Potuz
1462b7e57e Add show-private-keys flag to accounts-v2 list (#7487)
* Add show-private-keys flag to accoutns-v2 list

* fix fmt

* added tests and fixed return to 32 bytes

* deferred a lock and removed unused method

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-15 16:08:52 +00:00
Nishant Das
ec9c6f30bf Remove Local Protection Flag (#7543) 2020-10-15 14:52:45 +00:00
Nishant Das
0b64a335c8 check chainstart (#7494)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-15 22:03:48 +08:00
bidlocode
1caf2ca96f Accept ToS: fix paths for windows (#7535)
* fix paths for windows

* gofmt
2020-10-15 03:58:57 +00:00
bidlocode
5f9ea35b3f Add terms of use acceptance requirement (#7527)
* add accept tos

* fix typos

* add fixes

* check tos after config file loaded

* extend test

* add TERMS_OF_SERVICE.md

* fix

* fix typos

* add accept tos flag to e2e

* add flag to help

* add VerifyTosAcceptedOrPrompt to slasher

* fix gofmt

* fix import

* fix bazel
2020-10-15 02:05:30 +00:00
terence tsao
7076a1ec4a More feature flag deletions (#7533)
* Delete disable state lock and init sync verbose flags

* Delete disable slashing broadcast

* Remove disable wait for sync, noise, eth1 cache, static subnet

* Remove enable broadcast recovery attemp and make it as default

* Remove disable head update on per attestation

* Revert disable att braodcast discovery attempt

* gazelle

* Fixed an anti pattern

* Add enableAttBroadcastDiscoveryAttempts back

* Add back WaitForSync

* Remove extra lines

* Use DisableDynamicCommitteeSubnets path per @prestonvanloon feedback

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 23:28:49 +00:00
Raul Jordan
a840fa563d Remove Accounts-V1 (#7532)
* remove accounts-v1

* get all tests to not panic

* all client tests passing

* fix node test

* eliminate old flags

* tidy up
2020-10-14 22:20:20 +00:00
Ivan Martinez
803d7c9bd2 Add functionality to retrieve all pending items from pools (#7530)
* Allow slashing pools to retrieve all items

* Add functionality to exits too to retrieve all exits

* Rename to noLimit

* ndo err

* Fix tests

* Fix test

* Fix test again

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-14 21:08:24 +00:00
Potuz
76300cef09 Recommend non-HD wallets (#7524)
* Recommend non-HD wallets

* Fix ordering

* set non-HD wallet as first option

* fix go fmt

* changed keymanager-types-Kind enum

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-14 19:55:47 +00:00
terence tsao
e5ed2cd141 Remove feature flags within the scope of pkg (#7511)
* Remove feature flags within the scope of pkg

* Remove DisableForkChoice

* Remove e2e usages

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 18:34:49 +00:00
Victor Farazdagi
a005c77b3f Update error usage patterns to go1.13+ (#7529)
* rely on errors.Is

* wrap errors
2020-10-14 17:39:52 +00:00
terence tsao
8f04c555fc More feature flags removal (#7526)
* Remove disable domain cache

* Remove don't verify att sig flag

* Remove batch verify and attester copies

* Remove batch verify usage

* Update tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 16:18:40 +00:00
Radosław Kapka
0a007384c8 E2E cleanup (#7519)
* e2e cleanup

* export EpochTicker

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 15:17:33 +00:00
Nishant Das
022b6667e5 Use Custom SSZ for P2P Types (#7436)
* checkpoint progress

* add roundtrip tests

* change all

* remove error response

* clean up

* Update beacon-chain/sync/error_test.go

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

* gaz

* fix tests

* fmt

* gaz

* change back

* fix again

* clean up

* deep source

* fix all tests

* add gaz

* 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-10-14 07:55:28 +00:00
Ivan Martinez
022b09f2e2 Eth2 API: node endpoints outline (#7522)
* Nodev1 outline

* Gaz

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 06:11:11 +00:00
Raul Jordan
2f6f79724f Include Policy Bot Application (#7523)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 04:14:38 +00:00
terence tsao
7de161e917 Remove disable ssz cache feature flag (#7513)
* Remove ssz cache flag and usages

* Fix TestBeaconState_ProtoBeaconStateCompatibility

* gazelle

* Add cache flag back for tests

* Revert previous changes

* Revert previous changes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 03:13:59 +00:00
Victor Farazdagi
b9844024b4 Update comments describing init-sync process (#7521)
* updates comments

* fetcher mode from config

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 01:44:46 +00:00
terence tsao
5cd6f65a2c Remove skip BLS verify flag (#7516)
* Remove skip BLS verify flag

* Update tests to use correct values

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-14 00:53:17 +00:00
Potuz
88083d1000 Add journald option for logger (#7463)
* Add journald option for logger

Fixes #7353

* fix docker images

* go mod tidy

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-14 00:10:57 +00:00
terence tsao
9e712e4598 Add justified block insertion to forkchoice when missed (#7520)
* Add justified block insertion to fork choice when missed

* Add regression test
2020-10-13 18:26:43 +00:00
Radosław Kapka
b742511193 Numeric conversion cleanup (#7465)
* validator count

* fix build errors

* fix test error

* randao mixes

* active indices

* lastReceivedMerkleIndex

* redundant conversions

* eth1FollowDistance

* refs

* fix compile error

* slasher

* validator

* revert changes to lastReceivedMerkleIndex

* remove todo

* fix references test

* fix committee test

* Revert "validator count"

This reverts commit 19b376e399.

# Conflicts:
#	beacon-chain/rpc/beacon/validators.go

* Revert "fix build errors"

This reverts commit f4acd6e977.

* Revert "fix test error"

This reverts commit 2a5c9eec63.

* Revert "randao mixes"

This reverts commit 2863f9c24d.

* Revert "active indices"

This reverts commit 6e8385f395.

* Revert "refs"

This reverts commit c64a153f67.

* Revert "fix references test"

This reverts commit fe773b55a6.

* Revert "fix committee test"

This reverts commit 7a0931c448.

* fix compilation errors

* Revert "slasher"

This reverts commit 8b34137931.

* trieutil

* some int() simplifications

* fix deepsource issues

* removed redundant fmt.Sprint

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-13 12:43:49 +00:00
terence tsao
aaabec5cb7 Remove current deprecated flags (#7512)
* Remove deprecated flags

* Remove usages in config

* Gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-13 06:38:41 +00:00
terence tsao
e9c23673c5 Remove inital sync don't verify att sig flag (#7517) 2020-10-13 06:08:21 +00:00
Radosław Kapka
06d16a24b9 Reduce deposit memory (#7478)
* remove deposit proof and pending deposits

* wip

* wip

* wip

* clean up logs/comments

* function for pruning deposits and feature flag

* remove log

* add flag to beacon flags

* addressed PR feedback from terence

* add test assertions for errors

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-12 18:10:49 +00:00
Victor Farazdagi
ac1a4a078c Fix reported anti patterns (#7501)
* merge var decl

* single append

* replace bytes.Compare -> bytes.Equal

* remove redundant spritnf

* remove redundant spritnf

* trimprefix

* remove redundant nil check

* remove redundant return

* plain channel or unblock on context closing

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-12 16:12:00 +00:00
Victor Farazdagi
a019a0db4c Combines func params of the same type (#7500)
* combines func params

* update leftovers

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-12 15:43:19 +00:00
terence tsao
db48e12270 Update "Requesting parent block..." to debug level (#7508)
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-10-12 14:41:59 +00:00
terence tsao
9434d66ad0 Update Zinken deployment block (#7507)
* Simplify comparisons

* Update Zinken deployment block
2020-10-12 13:53:56 +00:00
Shay Zluf
3d0fc8bc64 Import old attestation store (#7466)
* import attestation to new data structure

* add tests

* add failure massages

* added signing root to data

* added signing root to data

* public keys 48 length

* remove redundant loop

* fix proposals

* fix manage dir name

* Omit redundant nil check on slices

* nishant feedback

* add test
2020-10-12 13:43:42 +03:00
Preston Van Loon
7cc32c4dda Various code inspection resolutions (#7438)
* remove unused code

* remove defer use in loop

* Remove unused methods and constants

* gofmt and gaz

* nilness check

* remove unused args

* Add TODO for refactoring subscribeWithBase to remove unused arg. It seems too involved to include in this sweeping PR. https://github.com/prysmaticlabs/prysm/issues/7437

* replace empty slice declaration

* Remove unnecessary type conversions

* remove redundant type declaration

* rename receivers to be consistent

* Remove bootnode query tool. It is now obsolete by discv5

* Remove relay node. It is no longer used or supported

* Revert "Remove relay node. It is no longer used or supported"

This reverts commit 4bd7717334.

* Delete unused test directory

* Delete unsupported gcp startup script

* Delete old k8s script

* build fixes

* fix build

* go mod tidy

* revert slasher/db/kv/block_header.go

* fix build

* remove redundant nil check

* combine func args

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-12 08:11:05 +00:00
bidlocode
0214553415 Fix config file flags in subcommands (#7475) 2020-10-11 08:26:59 -07:00
terence tsao
b5a913d862 Simplify comparisons ​(X-Y) == 0 (#7495) 2020-10-10 16:19:59 +00:00
Nishant Das
43765b5cb0 Register Subscribers After Node Is Synced (#7468)
* wait for synced

* fix again

* add test

* fix all

* fixes deepsource reported issue

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-10 16:50:28 +08:00
Victor Farazdagi
4c09e59b3b Remove duplicate imports (#7491)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-10 03:54:31 +00:00
Raul Jordan
551b03d6e6 Resolve Web UI Beta Testing Bugs (#7471)
* more descriptive password validation error

* include change wallet password fixes

* balance and jwt improvements

* allow for different wallet dirs specified on startup

* ensure wallet password is always validated

* fix up prysm tests

* gaz

* test pass

* pass balances tests

* wrap up fixes

* radek feedback

* fix up tests

* cors fix

* add tests for validator status

* pass tests

* fix n

* skip content type test

* package level cache and send over feed

* package level cache for derived

* all tests passing

* gofmt

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-10 02:07:28 +00:00
Potuz
c4e64afd07 Report on duplicate validator keys during imports (#7459)
* Fix #7393

* fix go fmt

* Add a test

* Convert to map of strings

* @terencechain fixes

* Update validator/keymanager/v2/direct/import.go

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

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-10 01:45:26 +00:00
Victor Farazdagi
d98a6dda8f Verify interface compliance using typed nil instead of dereferencing and conversion (#7489)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-10 00:36:48 +00:00
terence tsao
8aaa5b6ad0 Refactor ancestor lookup (#7472)
* Add ancestor root fall back to DB check

* Add a warning message

* Refactor ancestor lookups into seperate functions

* Update error string

* Fix has parent check and add a regression test

* Add a conext error test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-10 00:07:56 +00:00
Victor Farazdagi
f92244d497 Remove redundant err checking (#7488)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-09 23:39:23 +00:00
Preston Van Loon
e91165b0b4 Update validator UI to 0.0.1-alpha (#7486)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-09 22:06:23 +00:00
terence tsao
e15a0b08aa Remove duplicated StartSlot (#7484)
* Remove duplicated StartSlot

* Update existing tests

* Gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-09 21:23:49 +00:00
Raul Jordan
a3a77ab5a8 Open Web UI in Browser Automatically (#7481)
* open web

* Update shared/browser/browser_test.go

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

* Update shared/browser/browser.go

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

* add to depz.bazel

* run gazelle

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-09 19:51:46 +00:00
terence tsao
650ec797da Add missing mainet spec test (#7482) 2020-10-09 18:58:19 +00:00
Nishant Das
f629c72107 Tighten Up Snappy Framing (#7479)
* fix framing

* fix up conditions

* fix

* clean up

* change back

* simpler

* no need to cast

* Use math.MaxInt64

* gaz, gofmt

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-09 16:50:18 +00:00
Preston Van Loon
98a20766c9 Enable coverage for deepsource (#7441)
* Enable coverage for deepsource

* Add gocovmerge tool

* go mod tidy
2020-10-09 09:15:55 -07:00
Preston Van Loon
1f707842d2 Serve Prysm Web UI from Validator (#7470)
* Prysm web UI basic idea

* Refactor to use shared.Service interface, add sanity test

* register web server

* Determine mimetype

* Use 4242 as port for web

* Allow localhost or 127.0.0.1 for CORS. More tests, commentary

* Add flags, add site_data.go

* ignore site data

* Add sha

* gofmt

* gofmt

* fix script

* Lints

* fix vis

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-09 09:58:30 -05:00
dv8silencer
c944f29c7c Fix --clear-db on Windows (#7474)
* fix with text

* fix also for validator and add test

* handle error

* fix another test

* handle error

* gazelle

* fix bug in slasher as well

* gazelle
2020-10-09 09:28:35 +00:00
terence tsao
6b5265d2d4 Update slashing precompute to use config instead of hardcoded value (#7473) 2020-10-08 19:49:20 -07:00
terence tsao
8f64eb622e Optimize IsValidAttestationIndices unique sorted indices check (#7458)
* Optimize unique sorted indices check

* Add err handling for benchmark

* Gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 23:20:18 +00:00
Preston Van Loon
4ddacd57c6 fix blst build tag (#7443)
* fix blst build tag

* fix fuzz build

* remove buildkite specific bazelrc line

* remove conflicting kafka gotag in CI

* fix again

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-08 18:37:12 +00:00
Nishant Das
a66f434236 Listen to all Network Interfaces for discovery (#7434)
* listen to all ifaces for discovery

* fix test

* fix tests

* fix all tests

* Revert "fix all tests"

This reverts commit a5d6fffd45.

* Revert "fix tests"

This reverts commit b7a0cf5609.

* Revert "fix test"

This reverts commit 57e6218c68.

* fix and use loopback

* do properly

* fix

* listen to all ifaces

* fix bootnode

* make it trace

* make it loopback

* swap out

* change back

* fix e2e

* fix

* Update beacon-chain/p2p/discovery.go

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

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 15:16:18 +00:00
dv8silencer
796c336a29 Fix wallet check for Windows by addresses differences in error message text (#7461)
* fix

* test

Co-authored-by: dv8silencer <15720668+dv8silencer@users.noreply.github.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-08 14:30:08 +00:00
Nishant Das
48fcb08ebc Eth1 Handling Cleanup (#7467)
* clean up

* remove test
2020-10-08 13:47:16 +00:00
Shay Zluf
1315a15d9d Import proposal protection (#7430)
* Import proposals protection db

* Import old proposal protection data structure to new one

* test empty slots

* Update validator/db/kv/new_proposal_history.go

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

* Update validator/db/kv/new_proposal_history_test.go

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-08 11:51:50 +00:00
Radosław Kapka
25ebed9a70 Cache deposits only up to finalized block (#7453)
* cache deposits until finalized block

* take deposit index from state instead of block

* use stateByRoot

* use eth1data deposit count

* use depositCount-1

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 10:12:21 +00:00
terence tsao
703907bd99 Move ComputeProposerIndexWithValidators to test (#7460)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 09:24:17 +00:00
Preston Van Loon
d4e6ce6998 Fix deepsource findings (#7457)
* remove unused code

* Incomplete condition fix

* club append to single call

* anti-pattern fix 'should use for range instead of for { select {} }'

* use strings.ReplaceAll

* replace `len(parts[0]) == 0` with `parts[0] == ""`

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 08:36:47 +00:00
Preston Van Loon
390a589afb Disable BES in CI (#7462)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 07:17:35 +00:00
terence tsao
d34156bfe6 Add close to the body for e2e test (#7450)
* Add close to the body for e2e test

* Add error handling to defer

* Remove extra line

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-08 05:55:53 +00:00
bidlocode
7c8492e83f Add medalla flag (#7399)
* add --medalla flag for uniformity

* add enforcing testnet flag

* fix

* fix comments

* fix sufficient err msg

* fix shared method

* fix

* fix name

* fix name

* add test

* fix e2e

* fix gofmt

* fix test

* add warning

* fix warning

* fix warning test

* fix

* fix

* fix

* fix

* fix gofmt

* fix refactor to func

* add func description

* fix exported

* fix

* fix

* fix

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-07 23:04:19 +00:00
Preston Van Loon
668163d740 Revert PR #7429 to fix building on windows (#7456)
* Revert PR #7429 to fix building on windows

* Revert PR #7429 to fix building on windows

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-07 19:09:40 +00:00
terence tsao
7ad2929f0f Revamp proposer cache to fix lookahead bug (#7442)
* Add and test proposer indices cache

* Remove proposer indices usages from committee cache

* Adopt the new proposer indices cache

* Add comments on why genesis epoch is skipped

* Fix the failing tests

* Update beacon-chain/blockchain/process_block.go

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

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

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

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

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

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

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

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

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

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

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

* Address additional feedbacks from @prestonvanloon

* Add comments on why genesis epoch is skipped

* Refactor EndSlot to use StartSlot within

* Add proposer indices disabled

* Add libfuzz tags

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-07 17:25:08 +00:00
Victor Farazdagi
9ce64e2428 Refactor peer scorer into peerdata + scorers (#7452)
* updates comment

* manager -> service

* rename receiver

* refacgtor bad_responses

* refactor store

* update status service

* extends data service

* status service test

* refactor block provider scorer

* misc updates

* fix tests

* data -> peerdata

* gazelle

* peerdata/store test

* limit the visibility scope

* Nishant's suggestion

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-07 13:08:51 +00:00
terence tsao
ae78546323 Add Zinken flag to slasher (#7451)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-07 09:44:50 +00:00
Raul Jordan
23bce8d0c5 Include Deposit Data JSON in Wallet Create RPC Response (#7444)
* return deposit data for hd wallet create

* test added for deposit data json

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-07 02:15:54 +00:00
terence tsao
29137f7b39 Remove unused SlotSignature function (#7447)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-06 23:55:37 +00:00
Raul Jordan
bf4a8dcee9 Fix E2E Readme to Include Bazel Define Flag (#7449)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-06 20:49:29 +00:00
Shay Zluf
7b5f71229e New attestation store for local protection (#7248)
* Update attestation with new marshal unmarshal

* Add db methods to handle new slashing protection schema

* lint

* add tests

* goimports

* Apply suggestions from code review

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>

* const fix

* fix ineffectual assignments

* goimports

* fix import issue

* victor feedback fixes

* victor feedback fixes

* receiver methods

* receiver methods

* Update validator/db/kv/attestation_history_new.go

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

* Update validator/db/kv/attestation_history_new.go

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

* Update validator/db/kv/attestation_history_new.go

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

* Update validator/db/kv/attestation_history_new.go

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

* Update validator/db/kv/attestation_history_new_test.go

* type change

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-06 19:59:36 +00:00
Raul Jordan
4d7797827e Concurrent Websocket Handlers for Log Streaming (#7428)
* concurrent conn with mutex

* add buffer size

* only localhost

* clarify caller needs to hold lock

* Update shared/logutil/stream.go

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

* Update shared/logutil/stream.go

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

* fix up 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-10-06 13:32:48 +00:00
terence tsao
c0ed43d920 Refactor head info for better usages for lock (#7432)
* Refactor head info for better usages for lock

* Fix headroot test to use [32]byte{}

* go fmt: issue introduced in #7429

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-06 10:57:18 +00:00
Victor Farazdagi
842c15856b Apply go fmt + tidy: issue introduced in #7429 (#7446) 2020-10-06 09:05:32 +00:00
Potuz
20ac925ee4 Add a journald log format option. (#7429)
* Add a journald log format option.

Add an accepted value "journald" for the --log-format flag so that
logs are directed to journald with the correct error level.

* fix docker images

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-06 04:37:16 +00:00
Raul Jordan
6e8ff10003 deep source toml (#7439) 2020-10-05 14:07:49 -07:00
Victor Farazdagi
419fad07cd Handle nil header properly in powchain service tests (#7435) 2020-10-05 10:10:31 +00:00
Ivan Martinez
cf1c346beb Eth2 API: Add outline for beacon endpoints (#7408)
* Start Beacon API outline

* Rename to v1

* Add impl

* Change to outline

* Add comments

* Remove unneeded items

* Fix linting

* tidy

* Fix visibility

* go.sum

* Fix deps

* Tidy

* Add check for interface type and fix pointers

* Fix pointer name

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-05 00:15:27 +00:00
Radosław Kapka
3e0b20529b Miscellaneous code quality improvements (#7414)
* anti-patterns

* performance issues

* handle skipped defer

* gazelle fix

* misc bug risks

* make logging of proposer slashings more robust

* simplify calling span.End()

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-04 15:03:10 +00:00
Raul Jordan
d9ae2073e2 Pagination Added to ListAccounts Validator RPC Call (#7422)
* Pagination tests to list accounts

* fetch all

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-03 17:26:39 -05:00
terence tsao
7b3efcf62b Move read lock after hasHeadState (#7427)
* Move read lock before hasHeadState

* Export the locked version

* Update beacon-chain/blockchain/head.go

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

* Update beacon-chain/blockchain/chain_info.go

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

* Update beacon-chain/blockchain/chain_info.go

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

* Update beacon-chain/blockchain/chain_info.go

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

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-03 20:53:05 +00:00
terence tsao
c7d01fd73c Add lock around fork choice store votes (#7426)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-03 05:48:34 +00:00
Preston Van Loon
2916d183e8 Pubsub: ensure better TopicIDs validation (#7418)
* Ensure better topicIDs validation, add tests

* go mod tidy

* fix tests

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-03 01:51:58 +00:00
terence tsao
c24fb792cb Add locks around head getters (#7423) 2020-10-03 00:45:59 +00:00
Raul Jordan
70f3fcdbd9 Implement Create Account via RPC (#7400)
* add ssz rules

* regenerate protos to include deposit message

* built to match the deposit cli

* derived test

* fix up nil item

* fix up more nil items

* preston suggestion

* comment

* add missing tests to build file

* fix busted tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-02 16:35:28 -05:00
Victor Farazdagi
ecfdb354a7 Add new static analyzer: ineffassign (#7413)
* test defined

* first working impl

* register analyzer

* cleanup

* removes unused code

* secure rand in slasher/detection/testing

* Updates test

* fixes ineffassign type checks

* one more

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-02 23:56:18 +03:00
terence tsao
690fa12f1a Check block attestation length for operation pool (#7420)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-02 20:08:06 +00:00
Nishant Das
63c1057ae6 add bootnode (#7415)
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-02 12:28:09 -07:00
Preston Van Loon
1eee1948bb Fall back to ValidationIgnore in the event of a validation panic (#7419)
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-02 11:33:45 -07:00
Victor Farazdagi
e36e9250f1 enable cryptorand analyzer in slasher (#7417) 2020-10-02 19:32:21 +03:00
Nishant Das
b589ddd774 use full hash (#7416) 2020-10-02 23:08:51 +08:00
Nishant Das
ba01abbc8f use valid build tags (#7411) 2020-10-02 12:45:58 +03:00
Nishant Das
fa82b09cec Optimize Fetching of Eth1 Blocks (#7386)
* optimize fetching

* tests and clean up

* improve comment

* more cleanup

* lint

* dont terminate lookup

* shay and radek's review

* fix test

* Update beacon-chain/powchain/block_reader.go

* gofmt

* cleanup

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: rkapka <rkapka@wp.pl>
2020-10-02 15:31:05 +08:00
dv8silencer
7d9a706cfa Warn if user is not using a supported platform (#7381)
* Add prereqs package

* Incorporate prereq check into the clients

* gazelle

* gazelle fix

* linter

* Add tests

* minor change in test

* finish up tests

* gazelle

* error during platform detection does not cause client to fail fast

Co-authored-by: dv8silencer <15720668+dv8silencer@users.noreply.github.com>
2020-10-02 09:45:34 +03:00
Raul Jordan
437bab7df0 Update EthereumAPIs (#7409)
* handle unknown validator

* tests passing

* tidy
2020-10-01 22:04:48 -04:00
bidlocode
ee747ca6d4 add display contract (#7407)
* add display contract
2020-10-01 22:55:49 +00:00
terence tsao
de93551332 Ensure span ends (#7405)
* Ensure span ends
* Merge refs/heads/master into span-ends
* Merge refs/heads/master into span-ends
* Add missed span end
* Merge branch 'span-ends' of github.com:prysmaticlabs/prysm into span-ends
* Merge refs/heads/master into span-ends
2020-10-01 21:13:27 +00:00
terence tsao
0839f10dbc Add lock around feature config (#7406)
* Add lock
2020-10-01 20:35:44 +00:00
Victor Farazdagi
d169b490fa Fix ineffectual assignments (#7403)
* update rpc/beacon
* more fixes to beacon-chain/rpc
* update beacon-chain/sync
* Merge refs/heads/master into fix-ineffectual-assignments
* updates beacon-chain/p2p
* Merge branch 'fix-ineffectual-assignments' of github.com:prysmaticlabs/prysm into fix-ineffectual-assignments
* update beacon-chain/*
* fix imports
* update beacon-chain/blockchain
* more updates
* Merge refs/heads/master into fix-ineffectual-assignments
* Merge branch 'master' into fix-ineffectual-assignments
* Merge refs/heads/master into fix-ineffectual-assignments
* next round of updated
* Merge branch 'fix-ineffectual-assignments' of github.com:prysmaticlabs/prysm into fix-ineffectual-assignments
* wrap up remaining items
2020-10-01 18:53:36 +00:00
terence tsao
490cf9b7ba Remove logging of password if fails (#7404)
* Remove logging of password if fails
2020-10-01 17:41:23 +00:00
Victor Farazdagi
95a5b4945b Fixes incorrect checks for errors in several tests (#7392)
* fixes TestServer_ListAssignments_Pagination_InputOutOfRange
* fixes TestServer_ListValidatorBalances_PaginationOutOfRange
* fix TestServer_ListAttestations_Genesis
* remove redundant TestServer_GetValidatorParticipation_DoesntExist and TestGetDuties_NextEpoch_CantFindValidatorIdx
* Merge branch 'master' into fix-invalid-errcheck-tests
* remove unnecessary import
* fix TestStore_OnAttestation
* fix TestStore_OnAttestationUsingCheckptCache
* fix TestVerifyBlkDescendant
* fix pagination tests
* fix account v2 tests
* fix account v2 tests (remote)
* fix TestServer_JWTInterceptor_BadToken
* Merge refs/heads/master into fix-invalid-errcheck-tests
2020-10-01 14:38:53 +00:00
Victor Farazdagi
4aea039324 Remove unused constant in round robin (#7402)
* remove unused constant
2020-10-01 13:02:47 +00:00
Raul Jordan
23181c8629 Implement Backup and Delete Accounts via RPC (#7397)
* begin with delete accounts impl

* delete tests passing

* started backup, delete tests all passing

* implement backup using zip

* backup implementation done with unzip tests

* full tests done

* used proper error codes

* remove comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-30 22:37:38 -05:00
Preston Van Loon
d23b247a82 DB: Return error when saving nil eth1data (#7396)
* Return an error on saving nil eth1data
* gofmt
* Merge branch 'master' into return-error-on-nil
* Merge refs/heads/master into return-error-on-nil
* Merge refs/heads/master into return-error-on-nil
2020-09-30 23:23:22 +00:00
terence tsao
5178474280 Check err for filterAttestationsForBlockInclusion (#7398)
* Check err for
* Merge refs/heads/master into check-err
2020-09-30 22:45:17 +00:00
terence tsao
d5caee35fa Update min genesis time for Zinken (#7395)
* Update min genesis time
* Merge refs/heads/master into update-zinken-config
2020-09-30 22:09:23 +00:00
bidlocode
558ee2678b Optional services flags (#7358)
* add DisableMonitoringFlag(--disable-monitoring) to validator
* add EnableRPCFlag(--rpc) to validator (now rpc and grpc-gateway disabled by default)
* add DisableMonitoringFlag(--disable-monitoring) to slasher
* Merge branch 'master' of https://github.com/prysmaticlabs/prysm into optional-services-flags
* Merge branch 'master' of https://github.com/prysmaticlabs/prysm into optional-services-flags
* Merge branch 'master' into optional-services-flags
2020-09-30 20:55:56 +00:00
Raul Jordan
e1f8a37710 Import Accounts RPC Implementation (#7389)
* implement the import function

* begin tests for import keystores and add preconditions

* import implementation done

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-30 14:03:54 -05:00
terence tsao
e07b71b81d Add Zinken config (#7391) 2020-09-30 11:19:05 -07:00
Victor Farazdagi
db92d90309 Removes unused validator flags (#7388)
* removes unused validator flags
* Merge branch 'master' into remove-unused-validator-flags
2020-09-30 16:55:18 +00:00
terence tsao
e2eb2fb0d8 Ensure genesis state retrieval doesn't use zero hashes root (#7378)
* Cover genesis zero hashes case
* Merge branch 'master' into genesis-zero-hashes
* Cover an edge case pre genesis with fresh db
* Move state by root outside of the if
* Merge refs/heads/master into genesis-zero-hashes
* Clarify comments on why zero hashes used
* Merge branch 'genesis-zero-hashes' of github.com:prysmaticlabs/prysm into genesis-zero-hashes
* Merge refs/heads/master into genesis-zero-hashes
* Merge refs/heads/master into genesis-zero-hashes
* Merge refs/heads/master into genesis-zero-hashes
2020-09-30 15:41:09 +00:00
Shay Zluf
953960c860 Add slasher support for different testnets (#7385)
* Add slasher support for different testnets
* Merge branch 'master' into slasher_testnet_support
2020-09-30 15:08:03 +00:00
dv8silencer
7664eab32d Introduce checks for existing wallets into two edge cases (#7349)
* Add check for preexisting wallet

* Reminder

* Create another check.  Adjust tests

* Wording in comment

* Remove unnecessary logic.  Add another regression test.

* Spacing

* Prepare to merge master

* Refactor wallet checks

* Fixed test

* Revert back to original location of check

* Fix test

* Fix test

* Address linter feedback

* Align CreateWallet() with recent changes

* Align RecoverWallet with recent changes

* Correct test error message

* Refactor test to minimize duplication

* rename to isValid and adjust function code

* refactor

* Improve IsValid()

* Fix tests

* Remove comment

* Fix documentation of IsValid()

* Align behavior of OpenWalletOrElseCli

* Fix tests

* Realigning error msg with prior behavior

* Fix another test

* Correct logic

* small change in logic

* Fix err messages

* Create consts for repeated strings

* Add comments to new constants

* gofmt

* Adjust WalletConfig behavior so it is closer to prior-to-PR.  Adjust test accordingly

* adjust error messages

Co-authored-by: dv8silencer <15720668+dv8silencer@users.noreply.github.com>
2020-09-30 16:13:37 +02:00
Raul Jordan
16cdcf5dec Remove Deposit Command from Validator Client (#7379)
* remove deposit code
* Merge refs/heads/master into remove-deposit
2020-09-30 06:42:16 +00:00
Nishant Das
3b5ef50733 Fix Finalized Epoch Checks (#7364)
* fix up epoch checks

* build

* comp tests

* preston's comment
2020-09-30 08:25:25 +08:00
George Carder
529554f3f9 accommodate systems that use sha256sum (#7370)
* accommodate systems that use sha256sum
* cleaner use of checkSum
* Merge branch 'master' into shell_script_support4_sha256sum
* Merge branch 'master' into shell_script_support4_sha256sum
2020-09-29 12:22:35 +00:00
Radosław Kapka
fe9921457c Fix failing static analyzer tests (#7363)
* add "want" expectations
* add build step with analyzer tests
* add colon to yml
* Merge refs/heads/master into fix-analyzer-test-expectations
* Merge refs/heads/master into fix-analyzer-test-expectations
* Merge refs/heads/master into fix-analyzer-test-expectations
* Merge refs/heads/master into fix-analyzer-test-expectations
* remove tests from CI
* readme file
* change header size
2020-09-29 11:29:40 +00:00
terence tsao
bedb16cfb0 Update badge to v0.12.3 (#7367)
* Update badge to v0.12.3
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
2020-09-29 06:10:11 +00:00
Preston Van Loon
0921c00094 Remove processSlots from slashing check (#7357)
* Remove processSlots from slashing check

* imports

* imports

* PR feedback from @nisdas

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-29 13:22:55 +08:00
Raul Jordan
6ef4995329 Remaining Proto Definitions for Validator RPC Methods (#7368)
* import, delete, backup, and create acct
* Merge branch 'master' into rpc-changes
* impl methods
* Merge branch 'rpc-changes' of github.com:prysmaticlabs/prysm into rpc-changes
* wallet import comment
2020-09-29 01:58:14 +00:00
Victor Farazdagi
1e0b4e150e Fixes NotNil assertion (#7365)
* fixes NotNil assertion
* cover case of basic types
* removes redundant line
* Update TestStore_UpdateCheckpointState
* fixes TestPruneHistoryBlkHdr
2020-09-28 21:32:58 +00:00
Radosław Kapka
951c139cff Fix URL to voluntary exit documentation (#7361)
* fix documentation URL
2020-09-27 22:12:28 +00:00
terence tsao
eb3e4944e9 Ensure block root is non zeros for setting head before genesis (#7359)
* Ensure block root is non zeros for setting head
* Merge branch 'master' into can-set-head-genesis
* Merge refs/heads/master into can-set-head-genesis
2020-09-27 21:09:08 +00:00
terence tsao
bb98046608 Fix ListValidators inactive check (#7354)
* Fix ListValidators inactive check
* Updated an existing test
* Merge refs/heads/master into fix-list-validators
2020-09-27 20:30:03 +00:00
Eduard Klementiev
4ac0bbca19 gRPC load balancing (#7133)
* gRPC load balancing
* Fix typo
* Merge branch 'master' into 5132-gRPC-client-load-balancing
* Add doc about load balancer
* Update validator/client/multiple_endpoints_grpc_resolver.go
* Merge branch 'master' into 5132-gRPC-client-load-balancing
* gofmt
* Merge branch 'master' into 5132-gRPC-client-load-balancing
* Merge branch 'master' into 5132-gRPC-client-load-balancing
2020-09-27 18:08:28 +00:00
dv8silencer
c0c34f3d3a Fix panic that happens if you wallet-v2 recover 1 account (#7351)
* Bugfix
* Regression test.
* Remove unnecessary code.
* Merge branch 'master' into dv8-i7350
2020-09-26 10:13:56 +00:00
Nishant Das
77c95f3051 Add New Compiler Flags for BLST (#7352)
* add new c opts
* remove
* add to asm
* fix up benchamrks
* Merge refs/heads/master into addNewOpts
2020-09-26 08:48:02 +00:00
terence tsao
68d0c09daf Add, use and test VerifyWeakSubjectivityRoot (#7344)
* Add, use and test `VerifyWeakSubjectivityRoot`
* Comments
* Make bazel test happy
* Merge branch 'master' into verify-ws
* Add flag to help
* Merge branch 'verify-ws' of github.com:prysmaticlabs/prysm into verify-ws
* Merge refs/heads/master into verify-ws
* Merge refs/heads/master into verify-ws
* Merge refs/heads/master into verify-ws
* Merge branch 'master' of github.com:prysmaticlabs/prysm into verify-ws
* Update beacon-chain/blockchain/service.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
* Update beacon-chain/blockchain/weak_subjectivity_checks.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
* Merge branch 'verify-ws' of github.com:prysmaticlabs/prysm into verify-ws
* s/&&/|| for VerifyWeakSubjectivityRoot circuit breaker
* Merge refs/heads/master into verify-ws
* Merge refs/heads/master into verify-ws
2020-09-26 08:04:07 +00:00
Raul Jordan
282f3eec01 Display More Info for Validating Keys on Startup (#7347)
* display more info for wallet
* Merge refs/heads/master into display-info-for-keys
2020-09-25 20:43:12 +00:00
Raul Jordan
4a549ffe2b Warn About Deprecation of Accounts-V1 Within the Next 2 Releases (#7348)
* deprecation of accounts v1 error log
2020-09-25 18:24:31 +00:00
Nishant Das
d138c608bc Disable Libp2p Protocols (#7345)
* disable
2020-09-25 12:33:28 +00:00
Nishant Das
c7ff3a4f22 Better Chainstart Logging (#7336)
* better chainstart logging
* single threaded
* Merge branch 'master' into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* Merge refs/heads/master into betterChainstartLogging
* improve formatting
2020-09-25 04:31:23 +00:00
Nishant Das
7a96412ef2 Reject Messages With Invalid Fields in GossipSub (#7337)
* strict no sign
* Merge branch 'master' into StrictNoSign
2020-09-24 23:53:15 +00:00
Raul Jordan
5821454ac7 Implement Wallet Config and HasWallet Endpoints (#7341)
* fix the wallet config implementation

* implemented wallet config endpoint and tests

* better error messages

* fix nil pointer

* more nil issues fix

* gazelle

* fix interceptor

* revise

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-24 15:37:59 -05:00
terence tsao
90978cd22e Reset hot state cache size to 32 (#7340)
* Reset hot state cache size to 32
* Merge refs/heads/master into revert-hot-state-cache-size
2020-09-24 18:10:02 +00:00
Raul Jordan
76a3070fd7 Fix Change Wallet Password Logic (#7324)
* fix change password logic
* gaz
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
* Merge refs/heads/master into change-password-fix
2020-09-24 16:47:13 +00:00
terence tsao
1bc0cc7049 Skip duplicated aggregated attestation in pending queue (#7326)
* Skip duplicated aggregated atts
* Test
* Fixed a regression test
* Merge branch 'master' of github.com:prysmaticlabs/prysm into skip-dup-aggregator
* Go fmt
* Merge refs/heads/master into skip-dup-aggregator
2020-09-24 15:47:03 +00:00
terence tsao
ff69375fbd Revert 7242: Opt out --use-check-point-cache (#7338)
* revert bb37436
2020-09-24 15:03:35 +00:00
Victor Farazdagi
5b814009fa Improves test coverage of init-sync queue (#7320)
* basic invariants for all state transition handlers

* TestBlocksQueue_onCheckStaleEvent extended

* TestBlocksQueue_onScheduleEvent extended

* TestBlocksQueue_onDataReceivedEvent extended

* removes redundant ctx setting

* TestBlocksQueue_onReadyToSendEvent extended

* TestBlocksQueue_onProcessSkippedEvent extended

* test to highest slot update

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-24 21:39:46 +08:00
Radosław Kapka
99164761f5 Make voluntary exits release-ready (#7305)
* phrase validation utility
* use passphrase from docs portal
* enable voluntary exits
* Merge branch 'master' into enable-exits
* rename 'voluntary-exit' to 'exit'
* change passphrase
* gazelle
* change constant to error variable
* Merge branch 'master' into enable-exits
* rename error variable
* build fix
* Merge refs/heads/master into enable-exits
* do not remove whitespace in the middle
* Merge refs/heads/master into enable-exits
* Merge refs/heads/master into enable-exits
* Merge refs/heads/master into enable-exits
* Merge refs/heads/master into enable-exits
* code review changes
* Merge refs/heads/master into enable-exits
* Merge refs/heads/master into enable-exits
2020-09-24 11:00:44 +00:00
Radosław Kapka
e1cd9143e0 Package-level comments for static analyzers (#7332)
* package-level comments
* Merge refs/heads/master into analyzer-package-comments
2020-09-24 10:25:55 +00:00
Nishant Das
4d232feda8 Add Spadina Bootnodes (#7330)
* add spadina bootnodes
* add in bootnode
2020-09-24 09:49:24 +00:00
Nishant Das
d687270a89 Update BLST to Latest Commit (#7328)
* update blst
* Merge branch 'master' into updateBLST
2020-09-24 08:34:09 +00:00
Nishant Das
6d8207801c Update Bootnode With New Flags (#7327)
* update bootnode
* gaz
* Update BUILD.bazel
2020-09-24 07:02:36 +00:00
Preston Van Loon
6ad117b175 Return an error when any of the eth1 clients are nil (#7323)
* Return an error when any of the eth1 clients are nil
* return error if eth1DataFetcher is nil
* Annotate span
* gaz
* fix build and add tests
* dear linter, please accept this commit as tribute and let my PR pass
* Merge refs/heads/master into fix-7322
2020-09-23 23:16:06 +00:00
terence tsao
f9e062407f Fix an edge case when loading replay start state by slot (#7313)
* Ensure start state is the parent of the first block
* Regression test
* Merge branch 'master' into state-by-slot-state-state
* Add back the line
* Merge branch 'state-by-slot-state-state' of github.com:prysmaticlabs/prysm into state-by-slot-state-state
* Add a test for lower slot block condition
2020-09-23 21:39:16 +00:00
Radosław Kapka
dca93ce641 Unnecessary Slice-to-Slice Conversion analyzer (#7321)
* analyzer with tests
* fix bazel file
* modify analyzer to fix build issues
* add analyzer to tool chain
* remove arrays from inspections
* fix redundant [:] operator
* Merge branch 'master' into use-slice-directly
* Merge branch 'master' into use-slice-directly
* fix another inspection
* add package-level comment
2020-09-23 16:14:34 +00:00
Nishant Das
347aa14a28 Fix Bazel Reference For Go-Ethereum (#7318)
* fix api change
2020-09-23 10:20:08 +00:00
Victor Farazdagi
3621b2ff25 Better naming for constructor funcs (#7316)
* sync/initial-sync
* NewBeaconClientService -> NewService
* NewSlashingProtectionService -> NewService
* NewPrometheusService -> NewService
* NewColdStartService -> NewService
* NewRegularSync -> NewService
* NewDetectionService -> NewService
* NewWallet -> New
* NewKeystore -> New
* Merge branch 'master' into better-naming
* Merge branch 'master' into better-naming
* NewDepositCache -> New
2020-09-23 08:59:49 +00:00
Nishant Das
49ae42c249 Fix Validator For Spadina (#7314)
* fix commands
* Merge refs/heads/master into fixSpadina
2020-09-23 08:03:13 +00:00
Victor Farazdagi
1ce7cd5f50 Init sync: minor refactoring and more tests for Service (#7286)
* removes redundant code
* removes redundant code
* removes redundant db
* removes redundant p2p
* servive - test future genesis
* more tests for service.Start()
* service - already synced test
* Merge branch 'master' into init-sync-more-service-tests
* Merge branch 'master' into init-sync-more-service-tests
* NewInitialSync to New (avoid stutter)
* TestService_markSynced
* more assertions
* TestService_Resync
* renames test
* Merge branch 'master' into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* Merge branch 'master' into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* Merge branch 'master' into init-sync-more-service-tests
* fixes e2e test
* Merge branch 'init-sync-more-service-tests' of github.com:prysmaticlabs/prysm into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* Merge refs/heads/master into init-sync-more-service-tests
* New -> NewInitialSync
2020-09-23 07:24:33 +00:00
terence tsao
305fdd2e1b Add spadina network name (#7309)
* Update spadina network name
* Merge refs/heads/master into update-config
* Merge refs/heads/master into update-config
* Merge refs/heads/master into update-config
* Merge refs/heads/master into update-config
2020-09-22 23:20:20 +00:00
terence tsao
984cb38680 Remove long deprecated historical regen states in DB (#7308)
* Remove long deprecated db state gen
* Remove long deprecated db state gen
* gazelle
* Delete pass through
* Merge refs/heads/master into rm-deprecated-regen
* Merge refs/heads/master into rm-deprecated-regen
* Merge refs/heads/master into rm-deprecated-regen
2020-09-22 22:57:50 +00:00
terence tsao
bbdd20e898 Log grpc error chain (#7307)
* Log error chain
* Merge refs/heads/master into error-msgs
* Merge refs/heads/master into error-msgs
2020-09-22 22:23:01 +00:00
Victor Farazdagi
568cd3c9ec Fixes e2e "chain started" check (#7311)
* fixes e2e test
2020-09-22 21:34:38 +00:00
Raul Jordan
b09b1f3fa5 Disallow Creation of Multiple Wallets at Wallet Path (#7290)
* disallow multiple wallet creation
* imports
* Merge branch 'master' into disallow-multiple-wallets
* resolve conflicting test
* Merge branch 'disallow-multiple-wallets' of github.com:prysmaticlabs/prysm into disallow-multiple-wallets
* test passes
* Merge refs/heads/master into disallow-multiple-wallets
* Merge refs/heads/master into disallow-multiple-wallets
* Merge refs/heads/master into disallow-multiple-wallets
* Merge refs/heads/master into disallow-multiple-wallets
* Merge refs/heads/master into disallow-multiple-wallets
* Merge refs/heads/master into disallow-multiple-wallets
* radek feedback
* Merge branch 'master' into disallow-multiple-wallets
2020-09-22 19:02:13 +00:00
Nishant Das
22bcfd2c34 Update Message ID (#7304)
* shorten message id
* Merge refs/heads/master into updateMessageID
* Merge refs/heads/master into updateMessageID
2020-09-22 15:23:33 +00:00
Raul Jordan
ba440abe2d Store Hashed Password to Wallet Path (#7295)
* store wallet pass on creation
* store wallet hash
* save hash to wallet dir
* initialize wallet hash
* gaz
* imports spacing
* remove mentions of hashed pass from db schema
* simplify the wallet hash code
* comment removal
* Merge branch 'master' into fix-password-override
* pass tests
* test fix
* Merge branch 'fix-password-override' of github.com:prysmaticlabs/prysm into fix-password-override
* remove extraneous printfs
* tests passing
* require auth for create wallet
* gaz
* fix signup logic
* Merge refs/heads/master into fix-password-override
* Merge refs/heads/master into fix-password-override
* Merge refs/heads/master into fix-password-override
* Merge refs/heads/master into fix-password-override
* Merge branch 'master' into fix-password-override
2020-09-22 14:49:07 +00:00
Nishant Das
09640ae22d Update Go-Ethereum Fork (#7303)
* update
* tidy
* Merge refs/heads/master into updateGeth
* remove metaData
* remove cloudflare
* Revert "remove cloudflare"

This reverts commit 687210f70f.
2020-09-22 13:23:45 +00:00
Nishant Das
719e99ffd9 Replace Roughtime With Timeutils Across Prysm (#7301)
* remove roughtime

* change all references

* rename

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-22 19:49:58 +08:00
Shay Zluf
1a4129f5a6 Fix prompt default handling (#7300)
* Fix prompt default handling
* Merge branch 'master' of github.com:prysmaticlabs/prysm into default_handling
* added test
* Merge branch 'master' of github.com:prysmaticlabs/prysm into default_handling
* Merge branch 'master' of github.com:prysmaticlabs/prysm into default_handling
2020-09-22 06:35:15 +00:00
Nishant Das
de3f112a05 Remove Roughtime Usage From Prysm (#7299)
* remove roughtime
* Merge branch 'master' into removeRoughtime
* Merge refs/heads/master into removeRoughtime
2020-09-22 05:47:01 +00:00
terence tsao
3734bfacce Add target epoch and slot consistency check (#7288)
* Add target epoch and slot consistency
* Remove debug logs
* Merge refs/heads/master into att-epoch-consistency
* Merge refs/heads/master into att-epoch-consistency
* Merge refs/heads/master into att-epoch-consistency
2020-09-22 05:13:12 +00:00
Shay Zluf
d5e2b51d66 Add slasher grpc logs (#7289)
* Add grpc logs
* gaz
* Merge refs/heads/master into add-connection-error-handling
* try to restart connection on status unavailable
* Merge branch 'add-connection-error-handling' of github.com:prysmaticlabs/prysm into add-connection-error-handling
* add retry on dial
* goimports
* Merge refs/heads/master into add-connection-error-handling
* gaz
* Merge branch 'add-connection-error-handling' of github.com:prysmaticlabs/prysm into add-connection-error-handling
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-connection-error-handling
2020-09-22 04:39:34 +00:00
terence tsao
cdd28abc4b Remove renovate.json (#7291)
* Remove renovate.json
* Merge refs/heads/master into rm-renovate
2020-09-21 22:54:24 +00:00
Preston Van Loon
8c8f59e242 Fix sha after v0.12.3 tarballs were re-uploaded. Unskip test to resolve #7277. (#7292)
* Fix sha after v0.12.3 tarballs were re-uploaded. Unskip test to resolve #7277.
2020-09-21 22:22:19 +00:00
Raul Jordan
b1f9f97062 Implement ChangeWalletPassword API Endpoint (#7273)
* allow changing wallet password

* wallet change password logic

* tests for wallet password changes

* more unit tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-21 14:44:43 -05:00
Victor Farazdagi
7545d3f2b3 Init sync refactor state initialization check + tests (#7285)
* refactor state initialization into waitForStateInitialization
* more tests
* redundant blank line
* Merge branch 'master' into init-sync-refactor-state-init
* moves comment up
* Nishant's suggestions + bit more refactoring
* Explicitly process error (Nishant's suggestion)
2020-09-21 12:20:26 +00:00
dv8silencer
bdf8bf7be2 Fix accounts-v2 backup so that it can backup HD wallet accounts (#7284)
* Bugfix

* Added test
2020-09-21 10:50:05 +02:00
terence tsao
b928e9531c Two more gossip validations for unaggregated atts subnet (#7278)
* Add two more gossip validations for unaggregated attestations

* Removed a typo log

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-20 08:31:10 +08:00
terence tsao
1f6afa8547 Add config PROPORTIONAL_SLASHING_MULTIPLIER (#7275)
* Add config
* Merge refs/heads/master into prop-slashing-mul
* Fixed a typo reported by Radek
* Merge branch 'prop-slashing-mul' of github.com:prysmaticlabs/prysm into prop-slashing-mul
2020-09-19 22:04:24 +00:00
terence tsao
303edbde58 Update spec tests to v0.12.3 (#7276)
* Update urls
* Update sha tags
* Fix paths
* Delete removed test
* Skipping  with an issue
2020-09-19 18:00:28 +00:00
dv8silencer
208ea56a9c Improve error message when creating a wallet in place of one that already exists (#7268)
* Tell user if content already exists at wallet create destination
* Added test
* changed wording
* capitalization
* Merge branch 'master' into dv8-i7264
* Merge branch 'master' into dv8-i7264
* Address PR comments

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

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

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

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

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
* Minor fix
* Improve test by addressing PR feedback.  Change variable name
* address PR comments
2020-09-18 21:01:46 +00:00
Victor Farazdagi
c8b91ba7b0 Attestation proposing: more tests (#7267)
* refactors test
* Merge branch 'master' into optimize-proposals
* more filtering and sorting proposer atts
* Merge branch 'master' into optimize-att-proposer
* Merge branch 'master' into optimize-att-proposer
* revert
* Terence's suggestion on naming
2020-09-18 17:16:31 +00:00
terence tsao
268df90ddd Update weak subjectivity check point computation (#7251) 2020-09-18 08:06:00 -07:00
Nishant Das
749aba8d09 Fix Blst Signature Copy Test (#7272)
* fix signature test
* Merge branch 'master' into fixLastTest
2020-09-18 12:04:39 +00:00
Shay Zluf
7920afb12e Add missing error handling in slasher (#7270)
* Add missing error handling in slasher
* Merge branch 'master' into missing_error
* Merge refs/heads/master into missing_error
2020-09-18 10:09:29 +00:00
Radosław Kapka
cc147c7097 Align eth1data Majority Vote with the spec (#7200)
* align voting with the spec
* Merge branch 'master' into eth1vote-spec-align
* remove redundant else statements
* add comment to exported variable
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge branch 'master' into eth1vote-spec-align

# Conflicts:
#	beacon-chain/rpc/validator/proposer_test.go
* refactor tests
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* fix mock POWChain
* move last block's time check and add more test cases
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
* Merge refs/heads/master into eth1vote-spec-align
2020-09-18 09:46:31 +00:00
Preston Van Loon
852082cdb4 Check that the headers are equal while ignoring the signature for proposer slashings (#7252)
* Check that the headers are equal while ignoring the signature for proposer slashings. Resolves https://github.com/sigp/beacon-fuzz/issues/74

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-18 17:10:14 +08:00
Preston Van Loon
e927a3d170 Streaming logs: add backfill of messages for new connections" (#7265)
* add backfill of logs

* Add test and gofmt
2020-09-17 19:34:03 -05:00
Raul Jordan
7c2096f209 Websocket Connection Fixes (#7263)
* socket improvements
* Merge branch 'master' into socket-fix
* Merge refs/heads/master into socket-fix
2020-09-17 19:55:34 +00:00
terence tsao
dcdf5d0eac Add and verify weak-subjectivity-checkpoint flag (#7256)
* Handle weak subjectivity input

* Typo

* Feedbacks

* Better error string @rauljordan

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-17 14:32:40 -05:00
terence tsao
3db6784990 Update Spadina fork version to 0x02 (#7261)
* Update Spadina fork version to 0x02
2020-09-17 18:50:01 +00:00
terence tsao
d51ead76eb Implement and test GetWeakSubjectivityCheckpoint (#7216)
* Implement and test GetWeakSubjectivityCheckpoint

* Go mod tidy

* Add mock

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-17 12:50:31 -05:00
Radosław Kapka
a2cf235687 No-op Instruction analyzer (#7249)
* analyzer, tests and fixes
* error check
* gazelle
* add more asserts
* Merge branch 'master' into nop-analyzer
* Merge refs/heads/master into nop-analyzer
* fix no-op in blst package
* Merge refs/heads/master into nop-analyzer
* add assert after mutation
* mark test as TODO
* add issue number to TODO
2020-09-17 16:18:19 +00:00
Victor Farazdagi
e1e233a6d0 Fix gazelle warning when fuzzing_enabled is not provided (#7260)
* adds fuzzing_enabled configurable files to gazelle ignore list
* more fine grained
2020-09-17 12:58:03 +00:00
Victor Farazdagi
76bac74562 Disables resync when init-sync is disabled (#7259)
* disables resync when init-sync is disabled
2020-09-17 11:42:57 +00:00
Nishant Das
a335bbbb61 Add Flag To Disable Initial Sync (#7258)
* add new flag
* terence's review
2020-09-17 06:11:21 +00:00
Nishant Das
913e4aa538 Fix IPV6 Address Retrieval (#7257)
* fix
2020-09-17 03:02:20 +00:00
Raul Jordan
4b4641bae3 Restructure Prysm Wallet V2 Package to Prevent Import Cycles (#7247)
* fix up tests

* fix test build

* tests pass

* imports and remove shadowing

* lint

* visibility

* lint fix

* wallet init

* remove v22

* fix imports

* fixed broken password test

* Update validator/accounts/v2/wallet_create.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>

* Update validator/rpc/server.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>

* Update validator/node/node.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>

* fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
2020-09-16 20:34:42 -05:00
Raul Jordan
6bfb2b1e46 Use Bufio Large Buffer Instead of Scanner for Large Files in E2E (#7254)
* use readline
* Fix
* max file buffer size
2020-09-16 23:41:41 +00:00
dv8silencer
a97de0d474 Use passphrase for HD-wallets (#7222)
* Use wallet password
* Fix test
* Address another test
* Address linter's feedback.
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Delete temp file
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Merge branch 'dv8-i7213' of https://github.com/dv8silencer/prysm into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Add regression test.
* Skip mnemonic confirmation
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
* Merge branch 'master' into dv8-i7213
2020-09-16 20:12:16 +00:00
terence tsao
f6d3c28ae1 Save cached blocks before Stop() in blockchains service (#7245)
* Save cached blocks before Stop()
* Merge refs/heads/master into save-cached-blocks
* Merge refs/heads/master into save-cached-blocks
* Merge refs/heads/master into save-cached-blocks
* Merge refs/heads/master into save-cached-blocks
* Merge refs/heads/master into save-cached-blocks
* Regression test
* Merge branch 'save-cached-blocks' of github.com:prysmaticlabs/prysm into save-cached-blocks
2020-09-16 16:55:14 +00:00
Raul Jordan
3197748240 Streaming Logs via Websocket Server (#7240)
* Log streaming proof of concept

* fix broken imports

* imports

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-16 09:03:52 -05:00
Preston Van Loon
14dbc2b74d Add blst for BLS (#6539)
* Add blst third party dep

* initial build

* add init

* blst passing tests

* add feature flag

* blst and herumi for spec tests

* maybe this works for mac

* Actually set feature flag

* Add stub for VerifyMultipleSignatures for blst

* verifyCompressed

* use correct cores sizes

* aggregate public keys

* add multi-sig verification

* encode not hash

* revert back

* go mod tidy

* update blst to latest commit

* add batch decompress

* fix

* add test

* gofmt

* update blst

* go mod tidy

* remove kubesec, fix

* mod tidy

* disable some remote cache

* disable some remote cache

* disable some remote cache

* disable some remote cache

* Switch to -D__ADX__

* update

* tidy

* fix build

* Make blst for only linux,amd64

* gofmt

* lint

* lint

* gazelle

* fix build tag

* more stub methods

* shift adx instructions to x86

* fix arm64

* Revert "fix arm64"

This reverts commit 4d34ac21b7.

* add one more in

* Revert "Revert "fix arm64""

This reverts commit 1c8ae24ad1.

* try darwin now

* Revert "try darwin now"

This reverts commit 6f884714b8.

* Add sha256

* remove TODO

* checkpoint

* finally builds

* fix up

* add tag

* try again

* explicit disabling

* remove

* select properly

* fix

* better

* make CI happy too

* Update .bazelrc

* Update .bazelrc

* fix tests

* revert back

* Update shared/bls/blst/public_key.go

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

* Update shared/bls/blst/public_key.go

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

* clean up tests

* more clean up

* clean up

* add

* Update shared/bls/blst/signature.go

* Update shared/bls/blst/signature.go

* Update .buildkite-bazelrc

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

* try again

* remove go tag

* revert change

* gaz

* gazelle ignore

Co-authored-by: nisdas <nishdas93@gmail.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-16 21:28:28 +08:00
terence tsao
b0917db4c7 Core pkg: properly return errs (#7246)
* Return errs instead of nils

* Update a few more tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-15 22:55:57 -05:00
terence tsao
ee4ebe4c38 Opt out batch verify (#7244) 2020-09-15 18:53:51 -07:00
Nishant Das
56d6e05196 QSP-16 Fix Support for IPv6 (#6363)
* checkpoint changes

* new changes

* comment

* clean up

* set

* fix

* fix more

* more stuff

* clean up

* clean up

* remove

* clean up

* clean up

* comment

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-16 08:17:22 +08:00
terence tsao
bb374362e4 Opt out --use-check-point-cache (#7242)
* Make check point info cache an opt-out
* Typo
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cp-cache-opt-out
2020-09-15 17:14:04 +00:00
dv8silencer
c1114fa6be Fix issue with direct wallet's password being overwritten by incorrect password during import. (#7212)
* Maintain working password instead of overwriting it.

* Check for error first

* fix test

* Address linter

* TEMP, INCOMPLETE;  Working on regression test

* WORK IN PROGRESS - changed promptutil to create a mock password reader

* Test working now

* Address testing bugs

* Spacing

* Comments.  Fixed counter bug.

* gazelle fix

Co-authored-by: dv8silencer <15720668+dv8silencer@users.noreply.github.com>
2020-09-15 09:52:07 -05:00
terence tsao
36c921c601 Add spadina config (#7235) 2020-09-14 21:21:46 -07:00
dv8silencer
f31f49582b Fix accounts-v2 deposit and related bugs (#7219) 2020-09-14 16:04:22 -07:00
Preston Van Loon
cebb62997d Add beacon state unmarshal fuzzer, afl support (#6625)
* Add AFL third_party libraries

* add beacon state fuzzing, add afl fuzz bundle

* rm fuzzing engine

* fix and lint

* Check for array out of bounds when calculating proposer delta

* failing test

* fix

* Checkpoint progress

* Add requirement that inclusion distance is not zero, add regression test

* No need for HTR since that is covered in process slots

* Removing some fuzzit logic, old fuzz tests

* Add ssz encoder test and fix

* Fuzzing checkpoint, adding fuzzing to the p2p layer

* ignore some libfuzzer files

* Full testing of p2p processing of blocks, with some mocked stuff

* use tmpdir and always process blocks

* use checkptr

* Update ethereumapis

* go mod tidy

* benchmarks for ferran's fast ssz hash tree root

* Update fastssz

* fmt

* gaz

* goimports

* Fix

* fix ethereumapis

* fix again

* kafka

* fix gen file

* fix compute signing root

* gofmt

* checkpoint progress

* progress

* checkpoint

* updates

* updates

* merge fix

* WIP

* merge

* fix build

* fix merge related issues

* cleanup

* revert unrelated

* lint

* lint

* lint

* manual tags for fuzz

* Commentary on upload script

* some import fixes, but not all

* fix //fuzz:fuzz_tests

* rm unused test

* update generated ssz

* Set // +build libfuzzer

* remove debug code

* A bit of refactoring ot explain why there is a committee_disabled file

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-14 11:42:08 -07:00
Victor Farazdagi
e477df321c Updates proposer tests namings (#7234)
* adds proposer_ namespacing
* remove redundant string
* Merge branch 'master' into proposer-test-fix-naming
* Merge refs/heads/master into proposer-test-fix-naming
2020-09-14 12:55:20 +00:00
Radosław Kapka
828156b9d4 fix exit comment (#7233)
* fix exit comment
* Merge branch 'master' into fix-exit-comment
* Merge refs/heads/master into fix-exit-comment
2020-09-14 11:44:50 +00:00
Radosław Kapka
aaa3abf630 Shadowed Predeclared Indentifier analyzer (#7215)
* wip

* working for some ast nodes

* works for all but assignment

* works for all but mixed assignments

* change test name

* plug in the analyzer

* remove `copy` from predeclared list

* rename few shadowing names

* rename `len` to `length`

* add one more test case

* rename `panic` to `panicResult`

* replace `panic` with `panicResult` in error message

* remove test case not covered by the tool

* add `byte` to predeclared list

* additional test cases

* rename `copy` to `copyHandler`

* exclude functions with receivers

* revert to good names

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-14 12:49:15 +02:00
terence tsao
e1aa920fc6 Fix out of bound check in AncestorRoot (#7226)
* Move out of bound check to the correct scope
* Merge refs/heads/master into store-out-of-bound
2020-09-14 09:10:52 +00:00
Shay Zluf
fcfd828725 Local protection proposal schema update (#7197)
* Local protection schema update
* Merge branch 'master' of github.com:prysmaticlabs/prysm into proposal_protection_schema_update
* fix interface issue
* fix lint
* gaz
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Merge refs/heads/master into proposal_protection_schema_update
* Update validator/db/kv/new_proposal_history_test.go
2020-09-14 01:55:33 +00:00
terence tsao
3374a06f63 Skip initial roughtime result when EnableRoughtime is disabled (#7221) 2020-09-13 08:53:14 -07:00
Jim McDonald
0b497e57e4 Reverse error condition. (#7217)
* Reverse error condition.
2020-09-11 20:21:50 +00:00
Shay Zluf
af46fc7707 Fix propose protect error handling (#7188)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-11 09:53:53 -05:00
Radosław Kapka
b1e2238df9 Invert enable-finalized-deposits-cache (#7214)
* make flag opt-out
2020-09-11 09:49:24 +00:00
Shay Zluf
acddb6035a Fix rename issue (#7205)
* Fix rename issue

* nishant feedback

* add test

* Update shared/fileutil/fileutil.go

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

* preston feedback

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-11 00:56:58 +03:00
terence tsao
3147a5ee01 Check attestation slot before broadcast (#7209) 2020-09-10 13:16:35 -07:00
Victor Farazdagi
572227d25e Removes attestation pool pruning from UnaggregatedAttestations getter (#7204)
* removes att pool changing in getter
* test
* add prunning
* Merge refs/heads/master into no-pruning-in-unagg-att-getter
* Merge refs/heads/master into no-pruning-in-unagg-att-getter
* Merge refs/heads/master into no-pruning-in-unagg-att-getter
* Merge refs/heads/master into no-pruning-in-unagg-att-getter
2020-09-10 18:35:57 +00:00
terence tsao
84273e9a34 Implement helper method WeakSubjectivityCheckptEpoch (#7201)
* Implement and test WeakSubjectivityCheckptEpoch
* Merge refs/heads/master into get-wss
* Merge refs/heads/master into get-wss
* Merge refs/heads/master into get-wss
* Merge refs/heads/master into get-wss
* Update beacon-chain/core/helpers/slot_epoch.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-09-10 17:37:52 +00:00
Victor Farazdagi
114fac5149 Att aggregator filter by slot and index (#7206)
* Adds AggregateUnaggregatedAttestationsBySlotIndex method
* tests
* filter attestations by slot/index for aggregator to process
* Merge branch 'master' into att-aggregator-filter-by-slot-and-index
* Merge refs/heads/master into att-aggregator-filter-by-slot-and-index
* Merge refs/heads/master into att-aggregator-filter-by-slot-and-index
2020-09-10 15:55:45 +00:00
Victor Farazdagi
2d9fe5f2cf Disallows bitlist duplicates in seen_bits cache (#7203)
* disallows bitlist duplicates in seen_bits cache
* Merge refs/heads/master into upd-has-seen
2020-09-10 15:24:23 +00:00
Radosław Kapka
6daf45cb8f Correct accounts and validator error messages (#7207)
* incorrect account password
* misleading exit error
2020-09-10 14:49:13 +00:00
terence tsao
c8e93f8789 Verify indices in no verify method (#7199) 2020-09-09 13:38:19 -07:00
Radosław Kapka
94fa046ce1 Voluntary exit CLI/Client integration (#7162)
* rewrite of ProposeExit

# Conflicts:
#	validator/accounts/v2/accounts_exit.go

* translate todos to English

* use node client to calculate current epoch

* resolve dependency cycle

* add missing dependencies

* changed required epochs error message

* fix ProposeExit tests

* remove unused metrics

* simplify public-keys flag name

* organize CLI function

* fix incorrect list of exited keys

* fix formatting of non-exited keys

* add exit root to span attributes

* use errors instead of logs

* log info when all exits failed

* do not log stack trace for non-critical errors

* modify test asserts

* use standard way of displaying errors

* remove todo

* add missing function to wallet mock

* gazelle

* gazelle after stash

* move creating clients to separate function

* gazelle
2020-09-09 13:29:17 -05:00
Preston Van Loon
a74cf5de90 Replace context.Background() with more appropriate context (#7136)
* Replace context.Background() with more appropriate context
* replace a few context.TODO
* Merge refs/heads/master into fix-ctx
* Update validator/accounts/v2/accounts_create.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
* Fix tests
* fix stream tests
* gofmt
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* fix conflicts and remove ctx background uses
* fix broken test
* Merge branch 'master' into fix-ctx
* imports
* Merge branch 'fix-ctx' of github.com:prysmaticlabs/prysm into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* fix conflicts
* Merge refs/heads/master into fix-ctx
* fmt
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* Merge refs/heads/master into fix-ctx
* fixes tests
2020-09-09 09:48:52 +00:00
Raul Jordan
6d83770534 Fix Small Issue in Validator RPC Health Endpoint (#7195)
* amend node connection response
* imports
* fix err
* fix conf
* err
* test fix
* Merge branch 'master' into fix-health-endpoint
2020-09-08 22:35:31 +00:00
terence tsao
593442a0fa Fix span names in transition.go (#7192)
* Fix span names

* Go fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-08 14:36:02 -07:00
Raul Jordan
bd46abc71d Add Chain Genesis Info to Node Connection Response (#7194)
* amend node connection response
* imports
2020-09-08 20:54:56 +00:00
Raul Jordan
cb1f44872d Fix Health Reporting for Validator Client Node Connection (#7181)
* fix health reporting
* import
* Merge refs/heads/master into fix-health
* account test
* Merge branch 'fix-health' of github.com:prysmaticlabs/prysm into fix-health
* Merge refs/heads/master into fix-health
* Merge refs/heads/master into fix-health
* Merge refs/heads/master into fix-health
* Merge refs/heads/master into fix-health
* Merge branch 'fix-health' of github.com:prysmaticlabs/prysm into fix-health
* Merge refs/heads/master into fix-health
* Merge branch 'fix-health' of github.com:prysmaticlabs/prysm into fix-health
* Merge refs/heads/master into fix-health
* fmt
* Merge refs/heads/master into fix-health
2020-09-08 20:02:12 +00:00
Victor Farazdagi
8baa22f065 Fix unclosed tickers/timers (#7190)
* fix resource leak
* fixes leak in blocks fetcher
* client/validator release ticker resorces
* powchain, more straightforward ticker closing
* adds missing ticker.stop() calls
* more straightforward ticker closing
* Merge refs/heads/master into fix-unclosed-tickers-timers
* Merge refs/heads/master into fix-unclosed-tickers-timers
* Merge refs/heads/master into fix-unclosed-tickers-timers
* gofmt issues introduced in https://github.com/prysmaticlabs/prysm/pull/7176
2020-09-08 18:05:38 +00:00
Shay Zluf
f4848e46d4 Safer validator protection db dir (#7176)
* Safer validator protection db dir
* handle old account structure
* Merge refs/heads/master into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* fix e2e issue
* separate function
* Merge branch 'move_validator_protection_db' of github.com:prysmaticlabs/prysm into move_validator_protection_db
* Merge branch 'master' of github.com:prysmaticlabs/prysm into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* Merge refs/heads/master into move_validator_protection_db
* Update shared/fileutil/fileutil.go
* Merge refs/heads/master into move_validator_protection_db
2020-09-08 16:42:06 +00:00
terence tsao
f04fffb5fe Revert "Pipelines for ProcessBlockNoVerifyAttSigs and ProcessBlockStateRoot" (#7191)
* Revert "Pipelines for `ProcessBlockNoVerifyAttSigs` and `ProcessBlockStateRoot` (#7180)"

This reverts commit 9219dc77ff.
2020-09-08 15:45:20 +00:00
Victor Farazdagi
51f2cc18e5 Improves asyncutils/Debounce (#7189)
* improves asyncutils/debounce
* better handling of timeout test
* more tests
2020-09-08 14:49:28 +00:00
terence tsao
3de626f0d0 Prevent zero hashes sigs get submitted (#7187) 2020-09-07 12:53:30 -07:00
Nishant Das
a81214219d Hash Pubsub Messages Correctly (#7177)
* check message id

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-09-07 02:05:16 +08:00
terence tsao
245c18784e Ensure aggregateAndProofSig returns when err'ing (#7182)
* Return if sign fails
2020-09-06 06:56:17 +00:00
terence tsao
9219dc77ff Pipelines for ProcessBlockNoVerifyAttSigs and ProcessBlockStateRoot (#7180) 2020-09-04 16:24:43 -07:00
Raul Jordan
1de230110d Add Beacon Gateway Flag to Validator Client (#7179)
* add in cors for web ui in val client and gateway flag
* Merge branch 'master' into add-default-beacon-gateway
* gateway cors value
* Merge branch 'add-default-beacon-gateway' of github.com:prysmaticlabs/prysm into add-default-beacon-gateway
* fix tests
* Merge refs/heads/master into add-default-beacon-gateway
2020-09-04 19:03:18 +00:00
Victor Farazdagi
b6607fac25 Fixes timer resources leak in CountdownToGenesis (#7175)
* fixes timer leak in CountdownToGenesis
* Merge branch 'master' into fix-unclosed-timer-in-countdown
* Merge refs/heads/master into fix-unclosed-timer-in-countdown
2020-09-04 18:07:50 +00:00
terence tsao
e6277ec536 Revert 6966 (#7178)
* revert 6966

* Fix build
2020-09-04 12:25:42 -05:00
Raul Jordan
0961fef727 Implement Create and List Accounts Validator RPC (#7172)
* impl of accounts RPCs
* create and list accounts impls
* impl create account and list accounts
* tests pass
* imports
* fix test
2020-09-04 00:58:36 +00:00
Raul Jordan
366b98ac83 Add Node Connection Endpoint to Validator Client (#7171)
* add sync status checker
* register healthz
* simplify
2020-09-03 23:25:56 +00:00
terence tsao
c2425e81d7 Remove deprecated health end points (#7170)
* Remove deprecated health end points

* Remove fields
2020-09-03 17:39:30 -05:00
terence tsao
8f2950d374 Prevent far future target epoch for attestation state (#7169)
* Prevent far future target epoch

* Regression tests
2020-09-03 13:18:38 -05:00
Raul Jordan
f4a6864343 Prepare Validator Client for Web Usage (#7158)
* prepare validator for web usage
* wallet exists func in rpc server
* only initialize wallet if feed exists and wallet also exists
* enabling web via a feed
* wallet creation works but needs to be able to recover from mnemonic via api
* ensure logic works
* Merge branch 'master' into validator-web
* fix up tests
* test file
* wallet rpc tests
* add all tests to create wallet
* Merge branch 'master' into validator-web
* imports
* Merge branch 'validator-web' of github.com:prysmaticlabs/prysm into validator-web
* Merge refs/heads/master into validator-web
* Merge refs/heads/master into validator-web
2020-09-03 15:11:17 +00:00
Shay Zluf
c1a7c65e05 Deprecate beacon chain slasher flags (#7031)
* Deprecate beacon chain slasher flags
* Merge branch 'master' into deprecate_beacon_slasher_flags
* remove comments
* Merge branch 'deprecate_beacon_slasher_flags' of github.com:prysmaticlabs/prysm into deprecate_beacon_slasher_flags
* hidden
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* remove start slasher client
* de-depracate an in use flag in validator
* Merge branch 'master' of github.com:prysmaticlabs/prysm into deprecate_beacon_slasher_flags

# Conflicts:
#	shared/featureconfig/flags.go
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
* Merge refs/heads/master into deprecate_beacon_slasher_flags
2020-09-03 14:12:43 +00:00
Victor Farazdagi
7fd2536d54 Hardens block validation in init-sync (#7168)
* assert response invariants in beaconBlocksByRange
* Merge branch 'master' into assert-invariants-in-beaconblocksbyrange
* enforce specs invariant in requestBlocks
* blocks queue: onDataReceivedEvent - part1
* Merge branch 'master' into init-sync-block-validation
* blocks queue: onDataReceivedEvent - part2
* Merge branch 'master' into init-sync-block-validation
* block fetcher: test returned blocks validation
* gazelle
* Nishant's suggestion to not loop more than req.count of times
* combine checks
* enforce slot ordering
* enforce skip increments
2020-09-03 07:07:42 +00:00
terence tsao
0e6797d80d Set head as finalized root (instead of archived root) on start (#7167)
* Set head to finalized
* Merge branch 'master' into set-head-to-finalized
* Fixed testtttts
* Merge branch 'set-head-to-finalized' of github.com:prysmaticlabs/prysm into set-head-to-finalized
* Merge refs/heads/master into set-head-to-finalized
2020-09-02 22:43:40 +00:00
Victor Farazdagi
b2b4c2660d Asserts response invariants in beaconBlocksByRange (#7166)
* assert response invariants in beaconBlocksByRange
* Merge branch 'master' into assert-invariants-in-beaconblocksbyrange
2020-09-02 21:59:57 +00:00
Nishant Das
787857c38b Verify Attestation Time Correctly (#7160)
* add changes
* add unit test
* Merge refs/heads/master into fixVerifyAttTime
2020-09-02 19:21:52 +00:00
terence tsao
1cc21ed3c4 Check finalized ancestor (#7165) 2020-09-02 13:38:03 -05:00
terence tsao
7588e491ab Add overflow check for StartSlot (#7149)
* Add overflow checks
* More fixes
* Typos
* Merge branch 'master' into fix-overflow
* One more regression test
* Merge branch 'fix-overflow' of github.com:prysmaticlabs/prysm into fix-overflow
* Gazelle
* Merge branch 'master' into fix-overflow
* Nishant's feedback
* Merge refs/heads/master into fix-overflow
2020-09-02 02:52:36 +00:00
Raul Jordan
afce363e00 Update Protos for Wallet Creation (#7157)
* web api changes
* Merge branch 'master' into wallet-creation-protos
* protos checked in
* Merge branch 'wallet-creation-protos' of github.com:prysmaticlabs/prysm into wallet-creation-protos
2020-09-02 02:13:42 +00:00
Nishant Das
7de3ce0b31 Fix Snappy Framed Reader (#7152)
* add checks
* Merge refs/heads/master into fixFramedSnappy
* Merge refs/heads/master into fixFramedSnappy
* Merge refs/heads/master into fixFramedSnappy
* Merge refs/heads/master into fixFramedSnappy
2020-09-02 01:29:46 +00:00
terence tsao
6e6b871cc1 Use state slot to verify exit signature (#7155)
* Use state slot
* TestValidateVoluntaryExit_InvalidExitSlot
* Fixed TestProposeExit_NoPanic
* Merge refs/heads/master into use-correct-slot
2020-09-02 00:57:52 +00:00
Nishant Das
2349012bd0 Handle Zero Root Requests (#7151)
* handle zero root requests
* clean up
* Merge refs/heads/master into handleZeroRoots
* Merge refs/heads/master into handleZeroRoots
* Merge branch 'master' into handleZeroRoots
2020-09-01 19:09:09 +00:00
RoBiK75
b4c0a89d49 Fixes incorrect output produced by the ListAccounts function (#6976) (#7095)
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-09-01 13:13:44 -05:00
Nishant Das
d368156a08 Remove Deprecated Request Type (#7153)
* remove deprecated type
* fix build and tests
* update log
* Merge refs/heads/master into removeBlocksByRootType
2020-09-01 13:35:30 +00:00
Victor Farazdagi
63149a3dc3 Removes redundant SignedAggregateAndProof declaration (#7154)
* removes redundant SignedAggregateAndProof declaration
2020-09-01 13:11:05 +00:00
terence tsao
fbe088625a Update ProcessBlock to use a pipeline (#7148) 2020-08-31 18:29:27 -07:00
Raul Jordan
ecbab20bad Begin Dynamic Rescan of Validating Keys (#6963)
* begin on dynamic key rescan
* Merge branch 'master' into dynamic-rescan
* begin dynamic rescan
* fsnotify to listen for rescan dir changes
* recheck for slashing protection
* lint
* Merge branch 'master' into dynamic-rescan
* less aggressive recheck interval
* imports
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* resolve confs
* listen for file changes for accounts file
* reload accounts from keystore
* begin fixing rescan test
* add event feed
* fix confs
* fix conf
* fix broken tests
* Merge branch 'master' into dynamic-rescan
* simplify lines
* do nothing if no subscribers
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* fix tests
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* gaz
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* ident
* Update WORKSPACE
* gaz
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* add keys on service start
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* ensure debounce util works
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* complete refresh, debounce test, and ensure works at runtime
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* imports and remove log
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* Merge refs/heads/master into dynamic-rescan
* resolve confs
* fix up e2e tests
* Merge branch 'dynamic-rescan' of github.com:prysmaticlabs/prysm into dynamic-rescan
* fix up e2e
* Merge refs/heads/master into dynamic-rescan
2020-08-31 23:38:20 +00:00
Michael Huang
381b5be0fc Fix partially deposited status bug (#7138)
* Fix paritally deposited bug
* Replace conditional logic with depositStatus
* Add test
* Merge branch 'master' into fix-partial-dep-bug
* Merge branch 'master' into fix-partial-dep-bug
* Merge branch 'master' into fix-partial-dep-bug
* Merge branch 'master' into fix-partial-dep-bug
* Merge branch 'master' into fix-partial-dep-bug
2020-08-31 22:45:20 +00:00
Radosław Kapka
6803f3308a Implement exit proposal in validator client (#7125)
* Create mocks for updated ethereumapis

* Revert "Create mocks for updated ethereumapis"

This reverts commit 0da06d5158.

* update ethereumapis

* new metrics

* ProposeExit implementation and tests

* fix comments for metrics

* assert errors

* added one more error assert

* remove redundant comments

* make metric names compliant with best practices

* change root calculation

* fix test assertion

* fix test assertion

* check if domain is not nil

* extract error messages

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-31 15:18:22 -05:00
Raul Jordan
60558b7970 Refactor Accounts and Keymanager Methods to Not Rely on CLI (#7135)
* keymanagers no longer use cli ctx
* rename important values to keymanageropts
* further refactor accounts methods to reduce cli dependency
* separating cli vs non cli methods for various accounts functions
* recover wallet cli vs non-cli mode
* ensure half of tests build
* accounts v2 package now builds
* full revamp wallet creation or opening wallets
* everything builds
* tests pass finally
* Merge branch 'master' into no-cli-keymanagers
* ensure commands work as expected
* Merge branch 'no-cli-keymanagers' of github.com:prysmaticlabs/prysm into no-cli-keymanagers
* further fix build
* account creation comments
* fix imports and comments
* fix up failing test
* fix build
* Update derived.go
* Update direct.go
* Update remote.go
* Fixed variable
* fix up red tests
* use Cli instead of CLI, fix tests, and address Radek's feedback
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
* Merge refs/heads/master into no-cli-keymanagers
2020-08-31 19:46:45 +00:00
Ivan Martinez
7854b91ae0 E2E: Change metrics detection to use regex (#7145)
* Change metrics detection to use regex

* Fixes, remove println

* Forgot a println

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-31 13:35:26 -05:00
Victor Farazdagi
c9c7cc7b93 Fixes comments in params/config (#7147)
* fixes comments in params/config
* Merge refs/heads/master into params-doc-fix
* Merge refs/heads/master into params-doc-fix
2020-08-31 15:25:05 +00:00
terence tsao
b538f5073d Add metrics (#7142)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-31 07:51:47 -07:00
Nishant Das
3ed7b23ed7 Handle Saved Genesis Interop States (#7146)
* handle interop states
* lint
* Merge refs/heads/master into handleInteropCase
* fix test
* Merge branch 'handleInteropCase' of https://github.com/prysmaticlabs/geth-sharding into handleInteropCase
2020-08-31 13:45:03 +00:00
Nishant Das
c2b94d04ed Deprecate DisableNewStateMgmt Flag (#7124)
* deprecate flag
* gaz
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* Merge refs/heads/master into deprecateFlag
* add check back
2020-08-31 06:59:13 +00:00
Nishant Das
3316516d22 Harden Slot Time Verification (#7139)
* checkpoint

* lint

* terence's review

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-31 12:51:15 +08:00
Ivan Martinez
12c1daaf2b Verify deposits made and show network deposit is for (#6996)
* Verify deposits made and show network deposit is for
* Merge branch 'master' of github.com:prysmaticlabs/prysm into verify-deposit-netowrk
* Fix formatting
* gofmt
* Merge branch 'master' of github.com:prysmaticlabs/prysm into verify-deposit-netowrk
* Improve deposit sig failure error
* Merge branch 'master' of github.com:prysmaticlabs/prysm into verify-deposit-netowrk
* Fix fmt
* Add "verified for" text
* Update shared/params/config.go
* Merge branch 'master' into verify-deposit-netowrk
* Merge branch 'master' into verify-deposit-netowrk
2020-08-30 16:39:53 +00:00
terence tsao
f09620c9f6 Don't include orphaned atts (#7134)
* Don't include orphaned atts
* gazelle
* Merge refs/heads/master into orphaned-atts
2020-08-30 15:13:21 +00:00
Radosław Kapka
e47e7067c4 Update rpc validator exit tests (#7122)
* Create mocks for updated ethereumapis

* Revert "Create mocks for updated ethereumapis"

This reverts commit 0da06d5158.

* update ethereumapis

* change root calculation

* fix test assertion

* fix test assertion
2020-08-28 15:52:40 -05:00
Nishant Das
4edcf92140 Validate Beacon Block By Range Requests Better (#7132)
* checkpoint
* clean up
* new changes
* clean up
* victor's review
* victor's review
* fix test
2020-08-28 13:50:38 +00:00
terence tsao
7463f2cffd Update participation response (#7129)
* Sync with ethapi
* Implementation and test
* Handle mock
* Fix ProposeExit for e2e
* Merge refs/heads/master into participation
* Preston's feedback
* Merge branch 'participation' of github.com:prysmaticlabs/prysm into participation
2020-08-27 23:57:11 +00:00
terence tsao
fea2cc9e2f Cleanup stategen pkg (#7127)
* Clean up stategen
* Sync with master
* Fix tests
* Merge refs/heads/master into cleanup-newstate
* Merge refs/heads/master into cleanup-newstate
* Rename file
* Merge branch 'cleanup-newstate' of github.com:prysmaticlabs/prysm into cleanup-newstate
* gaz
* Forgot to add metrics page back
2020-08-27 22:29:59 +00:00
Victor Farazdagi
bd489e345a Fixes docs.go -> doc.go file name (#7128)
* fixes doc file name
* Merge refs/heads/master into fix-doc-file-name
2020-08-27 20:28:54 +00:00
Michael Huang
b98b9b740b Add PARTIALLY_DEPOSITED status (#7071)
* Update ethereumapis

* Add PARTIALLY_DEPOSITED status

* go mod tidy

* Fix bug

* Fixup

* Fixup

* Fix tests

* Revert fast ssz bump

* Pending status if deposit amount is 0

* go mod tidy

* More tests

* Trigger Buildkite

* Fix TestMultipleValidatorStatus_Indices

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-08-27 14:41:32 -05:00
Preston Van Loon
b7175b3482 Update fastssz: Attempt 2 (#7115)
* Revert "Revert "Update fastssz" (#7100)"

This reverts commit b954db9704.
* Preston's patch
* Merge branch 'master' of github.com:prysmaticlabs/prysm into revert-7100-revert-6760-update-fssz
* Update fssz, add regression test case
* more HTR with fssz
* fix some tests
* only one test left
* Make it so that HTR will work
* gofmt, imports
* gofmt, imports
* fix
* Merge branch 'master' of github.com:prysmaticlabs/prysm into revert-7100-revert-6760-update-fssz
* fix
* Merge branch 'master' into revert-7100-revert-6760-update-fssz
* Merge refs/heads/master into revert-7100-revert-6760-update-fssz
* gaz
* Merge branch 'revert-7100-revert-6760-update-fssz' of github.com:prysmaticlabs/prysm into revert-7100-revert-6760-update-fssz
* Merge refs/heads/master into revert-7100-revert-6760-update-fssz
* fix test
* Merge branch 'revert-7100-revert-6760-update-fssz' of github.com:prysmaticlabs/prysm into revert-7100-revert-6760-update-fssz
* Merge refs/heads/master into revert-7100-revert-6760-update-fssz
2020-08-27 18:13:32 +00:00
Preston Van Loon
7d28146e1e Return an error if no eth1 endpoint defined and we do not have genesis state (#7126)
* Return an error if no eth1 endpoint defined and we do not have genesis state
* Merge refs/heads/master into fail-without-genesis-state-and-no-eth1-node
2020-08-27 17:18:17 +00:00
Nishant Das
5bfc457904 Request Headers From ETH1 Node Instead of Blocks (#7121)
* request headers instead of blocks
* Merge branch 'master' into changeToHeader
* Apply suggestions from code review

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
* change references
* one more change
* last one
* Merge refs/heads/master into changeToHeader
2020-08-27 16:27:08 +00:00
Nishant Das
13324674ba disable default goerli endpoint (#7120)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-27 10:17:21 -05:00
Nishant Das
c78bfab69d Fix Go Builds (#7123)
* change to ssz DeepEqual
* gaz
2020-08-27 13:12:49 +00:00
terence tsao
2ee025ee88 Participation: count atts from orphaned blocks (#7117)
* Cound attestations from orphaned blocks

* Use next epoch's end slot

* Fixed a test

* Fixed a test

* Nishant's feedback

* Typo

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-27 16:19:55 +08:00
Radosław Kapka
0410b14260 Add deposit cache and majority vote to dev mode flags (#6768)
* enableFinalizedDepositsCache and enableEth1DataMajorityVote flags
* Merge branch 'master' into add-dev-mode-flags
* Merge branch 'master' into add-dev-mode-flags
* Merge branch 'master' into add-dev-mode-flags
2020-08-27 04:10:36 +00:00
terence tsao
2c3558e449 Remove new state mgmt (#7119) 2020-08-26 21:39:47 -05:00
Nishant Das
e95393f671 fix non existent validators (#7114) 2020-08-26 06:30:30 -07:00
Nishant Das
73cb6daf46 Listens For State Initialized Event (#7112)
* listen for state initialized event
* reg test
* fmt
* Merge refs/heads/master into handleNilHeadState
2020-08-26 10:54:33 +00:00
Nishant Das
8a8edf3743 Clean Up Metadata logs (#7109)
* clean errors

* cleaner

* gazelle

* go check

* Update beacon-chain/sync/error.go

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>
2020-08-26 17:59:16 +08:00
Fabrice Cheng
900e7114da Update VerifyMerkleBranch to match ETH2.0 spec (#6767)
* update VerifyMerkleBranch to match ETH2.0 spec
* Merge branch 'master' into 6705-refactor-verify-merkle-branch
* Make depth a parameter of VerifyMerkleBranch
* Merge branch '6705-refactor-verify-merkle-branch' of github.com-fabdarice:fabdarice/prysm into 6705-refactor-verify-merkle-branch
* Merge branch 'master' into 6705-refactor-verify-merkle-branch
* loop instead of appending
* Merge branch 'master' of https://github.com/prysmaticlabs/prysm into 6705-refactor-verify-merkle-branch
* Merge branch 'master' of https://github.com/prysmaticlabs/prysm into 6705-refactor-verify-merkle-branch
* fix int conversion
* Merge branch 'master' of https://github.com/prysmaticlabs/prysm into 6705-refactor-verify-merkle-branch
* Merge branch '6705-refactor-verify-merkle-branch' of github.com-fabdarice:fabdarice/prysm into 6705-refactor-verify-merkle-branch
* Merge branch 'master' into 6705-refactor-verify-merkle-branch
* fix keymanagerv2 tests
* revert print
* merge conflict
* fix bug during merge
* Merge branch 'master' into 6705-refactor-verify-merkle-branch
* Merge branch 'master' into 6705-refactor-verify-merkle-branch
2020-08-25 20:57:41 +00:00
Ivan Martinez
ba00c55f95 Accounts-V2: Fix wallet-v2 recover and wallet-v2 create for derived (#7104)
* Fix derived to create seed on wallet-v2 create
* Fix derived wallet recover
* Fix comment
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-derived-phrase
* Merge refs/heads/master into fix-derived-phrase
* Merge refs/heads/master into fix-derived-phrase
* Merge refs/heads/master into fix-derived-phrase
* Merge refs/heads/master into fix-derived-phrase
* Merge refs/heads/master into fix-derived-phrase
* Update validator/accounts/v2/wallet_create.go
* Merge refs/heads/master into fix-derived-phrase
2020-08-25 19:30:26 +00:00
Victor Farazdagi
8240eb0416 updates bazel-toolchains 3.1.1 -> 3.2.0 (#7107)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-25 13:28:37 -05:00
Victor Farazdagi
ba07ccb484 Apply testutils assertions: final cleanup (#7003)
* slasher/beaconclient tests
* slasher/db/kv tests
* Merge branch 'master' into apply-testutils-assertions-to-slasher
* fix build
* slasher/detection tests
* rest of the tests
* misc tests
* tools tests
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge branch 'master' into apply-testutils-assertions-misc
* agg tests
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge branch 'master' into apply-testutils-assertions-misc
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
* updates aggregated_test
* beacon-chain/operations/attestations/kv/* tests updated
* beacon-chain/operations/attestations tests updated
* beacon-chain/operations/slashings tests updated
* Merge branch 'master' into apply-testutils-assertions-misc
* gazelle
* beacon-chain/core tests updated
* fixes test
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
* beacon-chain/rpc tests updated
* beacon-chain/sync/initial-sync tests
* misc tests
* optimizes error message parsing in testutils
* Merge branch 'assertutils-optimize-processing' into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* endtoend tests
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
* gazelle
* Merge refs/heads/master into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* beacon-chain/blockchain tests updated
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
* beacon-chain/state/stategen tests updated
* beacon-chain all left-over tests are done
* Merge refs/heads/master into apply-testutils-assertions-misc
* validator tests updated
* slasher tests
* Merge branch 'master' into apply-testutils-assertions-misc
* gofmt
* gazelle
* Merge refs/heads/master into apply-testutils-assertions-misc
* shared upd
* end2end tests deps fixed
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
* Merge refs/heads/master into apply-testutils-assertions-misc
* misc
* all tests are updated
* Merge branch 'apply-testutils-assertions-misc' of github.com:prysmaticlabs/prysm into apply-testutils-assertions-misc
2020-08-25 15:23:06 +00:00
rkapka
3d9cde3e1c Modify majority vote rules (#6818)
* add deposit guard clauses to majority vote
* Merge branch 'origin-master' into majority-vote-deposit-count
* Merge branch 'master' into majority-vote-deposit-count
* uncommented e2e flag
* fix deposit comparison
* Merge branch 'origin-master' into majority-vote-deposit-count
* changed block height used for 0 deposits
* Merge branch 'master' into majority-vote-deposit-count
* exclude previous period's initial block
* rename first and last blocks
* renamed inRangeVotes arguments
* reorder arguments
* Comments explaining valid range calculation
* Merge branch 'master' into majority-vote-deposit-count
* Comments explaining deposit check
* logging
* process slots before voting for eth1data
* Merge branch 'origin-master' into majority-vote-deposit-count

# Conflicts:
#	beacon-chain/rpc/validator/proposer.go
* Merge branch 'master' into majority-vote-deposit-count
* Merge branch 'master' into majority-vote-deposit-count
* rollback changes to eth1data and randomETH1DataVote
* Merge branch 'master' into majority-vote-deposit-count
* Merge branch 'master' into majority-vote-deposit-count
2020-08-25 14:10:04 +00:00
Nishant Das
b291eb7953 Unset From,Sequence Number and Signature For Pubsub Messages (#7093)
* add new options
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
* Merge refs/heads/master into removePubsubFields
2020-08-25 11:08:42 +00:00
terence tsao
f61f02e59b First take of applying assertion funcs to shared tests (#6666)
* cmd tests
* deposit util tests
* feature config tests
* hashutil tests
* htr util tests
* interop tests
* ip util tests
* Update BLS
* Update cmd
* Update bytesutil and depositutil
* Update event
* Update keystore
* Update mathutil
* Update mputil
* Update pagination
* Update params
* Upate prome
* Update testutil
* Update trieutil
* Merge branch 'master' of github.com:prysmaticlabs/prysm into testutil-shared
* Sync with master
* Mod
* Typo
* Revert
* gazelle
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Gaz
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* Merge refs/heads/master into testutil-shared
* fixes build error
* Merge refs/heads/master into testutil-shared
2020-08-25 10:18:29 +00:00
Nishant Das
48fd40e35b fix interop (#7106) 2020-08-25 17:17:06 +08:00
Ivan Martinez
d8ea41ce35 Make Interop keys functional for accounts-v2 (#7103)
* Make Interop functional for accounts v2
* Merge branch 'master' into e2e-accounts-v2
* Fix e2e and account name fetch
* Merge branch 'e2e-accounts-v2' of github.com:prysmaticlabs/prysm into e2e-accounts-v2
* Enable metrics check
* Fix lint
* Merge branch 'master' into e2e-accounts-v2
2020-08-25 01:37:25 +00:00
Nishant Das
e556ac348a Add Shared Field Metrics (#7081)
* add metrics
* Merge branch 'master' into sharedFieldMetrics
* Merge branch 'master' into sharedFieldMetrics
* Merge branch 'master' into sharedFieldMetrics
* Merge branch 'master' into sharedFieldMetrics
2020-08-24 23:03:23 +00:00
terence tsao
c764099231 Use checkpoint info cache (#7098)
* Use checkpoint cache

* Add it to dev

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-24 17:11:45 -05:00
terence tsao
b954db9704 Revert "Update fastssz" (#7100)
* Revert "Update fastssz (#6760)"

This reverts commit 78a25f99c3.
* Merge refs/heads/master into revert-6760-update-fssz
2020-08-24 20:06:28 +00:00
Raul Jordan
c9c4cd9f87 Create Validator Accounts V2 Send Deposit (#7080)
* add in deposit logic
* create the deposit functionality
* import formatting and create deposit config
* proceed with retrieving user input for calling the deposit func
* actually send our the deposits
* better handling and comments
* programmatically send all
* lint
* gaz
* add progress bar
* deposit test
* better error handling
* Update validator/accounts/v2/accounts_deposit.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
* Merge refs/heads/master into send-deposit
2020-08-24 19:19:21 +00:00
Victor Farazdagi
880298d844 Optimizes error message parsing in testutils (#7096)
* optimizes error message parsing in testutils
* Merge refs/heads/master into assertutils-optimize-processing
* Merge refs/heads/master into assertutils-optimize-processing
2020-08-24 15:15:39 +00:00
Nishant Das
21a56d5419 Handle Nil Signature in Pending Queue (#7097)
* add fix and test

* Update beacon-chain/sync/pending_attestations_queue_test.go

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

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-08-24 22:54:58 +08:00
Victor Farazdagi
5c9830f0c3 More conservative selection of non-finalized peers (#7086)
* more conservative selection of non-finalized peers
* Merge refs/heads/master into init-sync-non-finalized-loop
* Nishant's suggestion on possible overflow
* Merge branch 'init-sync-non-finalized-loop' of github.com:prysmaticlabs/prysm into init-sync-non-finalized-loop
* Merge refs/heads/master into init-sync-non-finalized-loop
* Merge refs/heads/master into init-sync-non-finalized-loop
2020-08-24 14:07:21 +00:00
Victor Farazdagi
5d0f6c5b16 Fixes errNoPeersWithFinalizedBlocks naming (#7087)
* fixes errNoPeersWithFinalizedBlocks naming
* Merge refs/heads/master into init-sync-queue-fix-err-naming
* Merge refs/heads/master into init-sync-queue-fix-err-naming
2020-08-24 10:48:52 +00:00
Victor Farazdagi
5cee10f28e Adds DeepNotEqual assertion (#7092)
* adds deepnotequal func
2020-08-24 10:14:13 +00:00
Preston Van Loon
78a25f99c3 Update fastssz (#6760)
* Update fastssz
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update-fssz
* fmt
* gaz
* Merge refs/heads/master into update-fssz
* goimports
* Merge refs/heads/master into update-fssz
* Merge refs/heads/master into update-fssz
* Merge refs/heads/master into update-fssz
* Merge refs/heads/master into update-fssz
* Merge refs/heads/master into update-fssz
* Fix
* fix ethereumapis
* fix again
* kafka
* fix gen file
* fix compute signing root
* gofmt
* checkpoint progress
* progress
* checkpoint
* progress
* Fix build
* checkpoint
* helpers
* Another test fixed
* gaz
* another test fix
* gofmt
* some fixes
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update-fssz
* fix one test
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update-fssz
* fill empty checkpoint roots
* more padding
* more padding
* Fix //beacon-chain/rpc/debug:go_default_test
* fix //beacon-chain/core/state:go_default_test
* fix //beacon-chain/core/state:go_default_test
* fix some htr errors
* fix //slasher/rpc:go_default_test
* Progress on //beacon-chain/core/blocks:go_default_test
* Progress on //beacon-chain/core/blocks:go_default_test
* Progress on //beacon-chain/core/blocks:go_default_test
* fix //slasher/db/kv:go_default_test
* progress
* fix //beacon-chain/sync/initial-sync:go_raceon_test
* gofmt and gaz
* fix one more test, taking a break
* Fix //beacon-chain/core/blocks:go_default_test
* Complete beacon-chain/powchain
* Do most of beacon-chain/rpc/beacon/
* Do most of beacon-chain/blockchain
* fix //beacon-chain/operations/attestations/kv:go_default_test
* Fix //beacon-chain/cache/depositcache:go_default_test
* Fix //slasher/detection:go_default_test
* Progress
* fix //beacon-chain/rpc/validator:go_default_test
* gofmt
* fix //validator/client:go_default_test
* fix
* fix //beacon-chain/blockchain:go_raceoff_test
* fix //beacon-chain/rpc/beacon:go_default_test
* fix 1 of 4 shards in //beacon-chain/sync:go_default_test
* Fix //beacon-chain/sync:go_default_test and gofmt
* prevent panic
* fix //beacon-chain/state/stategen:go_default_test
* fix
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update-fssz
* fix most tests
* Self review, go mod tidy, run regen scripts
* fix slasher
* Update ethereumapis
* disable spawn strategy override
* Merge refs/heads/master into update-fssz
* Merge refs/heads/master into update-fssz
* Remove extra line in imports
* Remove extra line in imports
* Gofmt
* PR feedback from @nisdas
2020-08-24 01:46:17 +00:00
Preston Van Loon
706f375aed Healthz: Move header before write. Fixes #7029 (#7084)
* Healthz: Move header before write. Fixes #7029
* Merge refs/heads/master into fix-7029
2020-08-22 21:12:17 +00:00
terence tsao
5977343a0d UnaggregatedAttestations use helper hasSeenBit (#7083) 2020-08-22 13:42:55 -07:00
terence tsao
f2afeed9da Pool: Use a TTL cache for seen bits (#7015) 2020-08-21 16:27:51 -07:00
Raul Jordan
e69ed7c778 Accounts V2: Implement Backup for Derived Keymanager (#7067)
* backup for derived complete
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
* Merge refs/heads/master into derived-backup
2020-08-21 19:43:03 +00:00
Raul Jordan
c9caf5dfc5 Set Healthz to Return Error if Chain Has Not Yet Started (#7077)
* healthz in sync when chain not started
* Merge refs/heads/master into fix-healthz-when-process-deposits
* Merge refs/heads/master into fix-healthz-when-process-deposits
* Merge refs/heads/master into fix-healthz-when-process-deposits
2020-08-21 19:09:52 +00:00
Raul Jordan
b4c7a14759 Do Not Unset Rate Limiter Before Node Shutdown (#7078)
* reset rate limiter before shutdown
* Merge refs/heads/master into empty-rate-limit
* Merge refs/heads/master into empty-rate-limit
* Update beacon-chain/sync/service.go
2020-08-21 18:48:43 +00:00
Ivan Martinez
92e1a996cc Slasher: Optimize span marshal and unmarshal (#7062)
* Optimize marshal and unmarshal
* Merge branch 'master' into slasher-optimize-span
* Merge branch 'master' into slasher-optimize-span
* Add tests and comments
* Merge branch 'slasher-optimize-span' of github.com:prysmaticlabs/prysm into slasher-optimize-span
* Merge branch 'master' of github.com:prysmaticlabs/prysm into slasher-optimize-span
* Merge refs/heads/master into slasher-optimize-span
* Merge refs/heads/master into slasher-optimize-span
* Merge refs/heads/master into slasher-optimize-span
2020-08-21 17:29:11 +00:00
rkapka
6228b3cd9f Identical expression comparison analyzer (#7066)
* static analyzer with tests
* Merge branch 'origin-master' into identical-expression-comparison-analyzer
* resolve analyzer errors
* Merge branch 'origin-master' into identical-expression-comparison-analyzer
* change excluded file in nogo_config
* remove tests from bazel file
* exclude test file explicitly
* extracted common code to helper file
* Revert "extracted common code to helper file"

This reverts commit e9ccea7360.
* Merge refs/heads/master into identical-expression-comparison-analyzer
* Merge refs/heads/master into identical-expression-comparison-analyzer
2020-08-21 16:48:27 +00:00
terence tsao
8686a81304 Implement checkpt info cache (#7070) 2020-08-21 08:50:21 -07:00
Victor Farazdagi
05d6dc7a10 Improves block deduplication on batch processing (#7075)
* fixes block deduplication on batch processing
* Nishant's suggestions
2020-08-21 10:51:27 +00:00
terence tsao
ec1dd85c44 Fix identical expressions (#7069)
* Fix ident exps
* Merge refs/heads/master into fix-ident-exp
2020-08-20 22:34:52 +00:00
Roy
7b0b8ee126 Add prysm.sh1 for native Windows support via PowerShell (#6829)
* Add prysm.sh1 for native Windows support via PowerShell
* Remove unused variable
* Merge branch 'master' into master
* Merge branch 'master' into master
* Merge branch 'master' into master
* Merge branch 'master' into master
2020-08-20 20:52:59 +00:00
terence tsao
55074bcc6c Tidying up a few core functions (#6995)
* DB: add block roots test
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Pool: add seen atts map
* Pool: use seen atts map
* Pool: clear seen map
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Core: clean up unused noverify and tidy up namings
* Gaz
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Core: Add no verify back. Better namings
* Merge branch 'rm-no-verify' of github.com:prysmaticlabs/prysm into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Core: fixed a test
* Merge branch 'rm-no-verify' of github.com:prysmaticlabs/prysm into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
* Merge refs/heads/master into rm-no-verify
2020-08-20 19:53:22 +00:00
rkapka
89e279f9c8 Account commands cleanup (#7065)
* initial implementation of command
* Add second confirmation step
* Merge branch 'origin-master' into voluntary-exit-command
* fix variable name
* added unit tests
* Merge branch 'origin-master' into voluntary-exit-command
* add comment about stdin
* remove backup-related code from accounts_delete_test
* fix comments
* move filterPublicKeysFromUserInput to new account helper
* remove SkipMnemonicConfirmFlag
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* Merge refs/heads/master into voluntary-exit-command
* code review fixes
* removed commented-out code
* Merge branch 'voluntary-exit-command' into account-commands-cleanup

# Conflicts:
#	shared/promptutil/prompt.go
* Merge branch 'origin-master' into account-commands-cleanup

# Conflicts:
#	shared/promptutil/prompt.go
#	validator/accounts/v2/BUILD.bazel
#	validator/accounts/v2/accounts_exit.go
#	validator/accounts/v2/accounts_exit_test.go
* Merge refs/heads/master into account-commands-cleanup
2020-08-20 19:14:03 +00:00
terence tsao
40db6cb0cf Add slot in epoch (#7064)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-20 13:43:03 -05:00
rkapka
45e4ed25a3 Voluntary exit CLI command (#7046)
* initial implementation of command

* Add second confirmation step

* fix variable name

* added unit tests

* add comment about stdin

* code review fixes

* removed commented-out code

* added log assert

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-20 19:53:09 +02:00
terence tsao
e93d31c60e Use hot state cache for replay (#7063) 2020-08-20 08:53:10 -07:00
terence tsao
8bdf9db147 Add replay block count metric (#7060) 2020-08-20 06:20:26 -07:00
Shay Zluf
2bf1332e5c Slasher improvements (#7061)
* Slasher loging and span removal

* merge and reconnect fix

* ivan feedback
2020-08-20 10:31:16 +03:00
Nishant Das
7744c3ae47 Batch Block Roots Requesting (#7027)
* checkpoint
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into batchRootReq
* test
* gaz
* fix test
* comment
* Merge refs/heads/master into multipleBranchProcessing
* Merge refs/heads/master into multipleBranchProcessing
* Merge refs/heads/master into multipleBranchProcessing
* Merge refs/heads/master into multipleBranchProcessing
* Merge refs/heads/master into multipleBranchProcessing
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into batchRootReq
* terence's review
* Merge branch 'multipleBranchProcessing' of https://github.com/prysmaticlabs/geth-sharding into batchRootReq
2020-08-20 04:50:14 +00:00
Nishant Das
ba5da21026 Shift Sync Warn and Error Messages To Debug (#7059)
* change

* change
2020-08-20 11:30:41 +08:00
Preston Van Loon
395ea76f44 Save finalized checkpoint before migrate to cold (#7055)
* Save finalized checkpoint before migrate to cold
* Save finalized checkpoint before migrate to cold
* Merge branch 'master' into save-checkpoint-first
2020-08-19 21:11:44 +00:00
Preston Van Loon
3aa95b9c16 Use correct context for IsFinalizedBlock call (#7053)
* Use correct context for IsFinalizedBlock call
* Merge branch 'master' into use-correct-ctx
2020-08-19 19:55:39 +00:00
Ivan Martinez
bc20591b72 Accounts-V2: Change ListDirs() to Exists(), fix bug for derived (#7038)
* Change ListDirs() to Exists()
* Merge branch 'master' into fix-derived-pass
* Make function more accurate
* Merge branch 'fix-derived-pass' of github.com:prysmaticlabs/prysm into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
* Merge refs/heads/master into fix-derived-pass
2020-08-19 16:46:26 +00:00
Nishant Das
85a040bfd2 Default To Mainnet Config When Parsing Chain Config (#7052)
* add reg test
* Merge branch 'master' into defaultToMainnet
2020-08-19 15:42:24 +00:00
terence tsao
399dc85737 Use map to reject seen pending block (#7045) 2020-08-18 09:21:25 -07:00
Victor Farazdagi
9bf80219c9 Applies assertion funcs to slasher/* tests (#6998)
* slasher/beaconclient tests
* slasher/db/kv tests
* Merge branch 'master' into apply-testutils-assertions-to-slasher
* fix build
* slasher/detection tests
* rest of the tests
* misc tests
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Update slasher/db/kv/spanner_test.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>
* Update slasher/node/node_test.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
* Update slasher/db/kv/spanner_test.go
* Merge refs/heads/master into apply-testutils-assertions-to-slasher
2020-08-18 12:41:25 +00:00
Shay Zluf
14cd25f9dc Slasher span cache size flag (#7043)
* Span cache size by using flag
* Merge refs/heads/master into set_span_cache_size
2020-08-18 11:18:33 +00:00
Nishant Das
d81c9ffcfc Reject Duplicate Blocks From Being Saved (#7044)
* check for duplicates

* add test
2020-08-18 18:47:44 +08:00
Shay Zluf
27c8402ae0 Validator recheck slasher client status (#7041)
* Validator recheck slasher client status
* Merge branch 'master' into slasher_status_fix
* Merge branch 'master' into slasher_status_fix
* Merge refs/heads/master into slasher_status_fix
* Merge refs/heads/master into slasher_status_fix
2020-08-18 03:04:39 +00:00
1057 changed files with 59257 additions and 29241 deletions

View File

@@ -5,6 +5,9 @@ test --test_verbose_timeout_warnings
test --build_tests_only
test --test_output=errors
# E2E run with debug gotag
test:e2e --define gotags=debug
# Clearly indicate that coverage is enabled to disable certain nogo checks.
coverage --define=coverage_enabled=1
@@ -33,9 +36,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: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
# Release flags
build:release --workspace_status_command=./scripts/workspace_status.sh
build:release --stamp
@@ -69,18 +80,13 @@ build:fuzz --copt=-fno-omit-frame-pointer
build:fuzz --define=FUZZING_ENGINE=libfuzzer
build:fuzz --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
build:fuzz --linkopt -Wl,--no-as-needed
build:fuzz --define=gc_goopts=-d=libfuzzer
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
test:fuzz --local_test_jobs="HOST_CPUS*.5"
test:fuzzit --config=fuzz
test:fuzzit --test_env=FUZZIT_API_KEY
test:fuzzit --test_env=PRYSM_BUILD_IMAGE=gcr.io/prysmaticlabs/prysm-fuzzit:v0.11.0
test:fuzzit --test_timeout=1200
test:fuzzit --run_under=//tools:fuzzit_wrapper
# Build binary with cgo symbolizer for debugging / profiling.
build:cgo_symbolizer --config=llvm
build:cgo_symbolizer --copt=-g

View File

@@ -3,10 +3,10 @@
#
# 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 --spawn_strategy=standalone
build:remote-cache --strategy=Javac=standalone
build:remote-cache --strategy=Closure=standalone
build:remote-cache --strategy=Genrule=standalone
#build:remote-cache --spawn_strategy=standalone
#build:remote-cache --strategy=Javac=standalone
#build:remote-cache --strategy=Closure=standalone
#build:remote-cache --strategy=Genrule=standalone
# Prysm specific remote-cache properties.
#build:remote-cache --disk_cache=
@@ -34,16 +34,5 @@ build --flaky_test_attempts=5
# Disabled race detection due to unstable test results under constrained environment build kite
# build --features=race
# Enable kafka for CI tests only.
test --config=kafka_enabled
build --bes_backend=grpcs://builds.prylabs.net:1985
build --bes_results_url=https://builds.prylabs.net/invocation/
# Disable flaky test detection for fuzzing.
test:fuzz --flaky_test_attempts=1
# Expose test environment variables in CI
test:fuzzit --test_env=GITHUB_REF
test:fuzzit --test_env=GITHUB_SHA
test:fuzzit --test_env=DOCKER_HOST

12
.deepsource.toml Normal file
View File

@@ -0,0 +1,12 @@
version = 1
[[analyzers]]
name = "go"
enabled = true
[analyzers.meta]
import_paths = ["github.com/prysmaticlabs/prysm"]
[[analyzers]]
name = "test-coverage"
enabled = true

View File

@@ -43,7 +43,8 @@ jobs:
go get -v -t -d ./...
- name: Build
run: go build -v ./...
# Use blst tag to allow go and bazel builds for blst.
run: go build -v --tags=blst_enabled ./...
# Tests run via Bazel for now...
# - name: Test

4
.gitignore vendored
View File

@@ -29,3 +29,7 @@ password.txt
# Dist files
dist
# libfuzzer
oom-*
crash-*

91
.policy.yml Normal file
View File

@@ -0,0 +1,91 @@
policy:
approval:
- or:
- only test files are changed
- only proto files are changed
- touches consensus critical code
- touches sync/blockchain/p2p code
- large line count
- is critical priority
approval_rules:
- name: only test files are changed
if:
only_changed_files:
paths:
- "*_test.go"
- "*.bazel"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 1
teams:
- "prysmaticlabs/core-team"
- name: only proto files are changed
if:
only_changed_files:
paths:
- "*pb.go"
- "*pb.gw.go"
- "*.bazel"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 1
teams:
- "prysmaticlabs/core-team"
- name: touches consensus critical code
if:
only_changed_files:
paths:
- "beacon-chain/core/*"
- "beacon-chain/state/*"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 2
teams:
- "prysmaticlabs/core-team"
- name: touches sync/blockchain/p2p code
if:
only_changed_files:
paths:
- "beacon-chain/blockchain/*"
- "beacon-chain/sync/*"
- "beacon-chain/p2p/*"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 2
teams:
- "prysmaticlabs/core-team"
- name: large line count
if:
modified_lines:
total: "> 1000"
changed_files:
ignore:
- "*pb.go"
- "*pb.gw.go"
- "*.bazel"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 2
teams:
- "prysmaticlabs/core-team"
- name: is critical priority
if:
has_labels:
- "Priority: Critical"
options:
ignore_commits_by:
users: ["bulldozer[bot]"]
requires:
count: 3
teams:
- "prysmaticlabs/core-team"

View File

@@ -104,10 +104,14 @@ nogo(
"@org_golang_x_tools//go/analysis/passes/inspect:go_tool_library",
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_tool_library",
"//tools/analyzers/maligned:go_tool_library",
"//tools/analyzers/roughtime:go_tool_library",
"//tools/analyzers/cryptorand:go_tool_library",
"//tools/analyzers/errcheck:go_tool_library",
"//tools/analyzers/featureconfig:go_tool_library",
"//tools/analyzers/comparesame:go_tool_library",
"//tools/analyzers/shadowpredecl:go_tool_library",
"//tools/analyzers/nop:go_tool_library",
"//tools/analyzers/slicedirect:go_tool_library",
"//tools/analyzers/ineffassign:go_tool_library",
] + select({
# nogo checks that fail with coverage enabled.
":coverage_enabled": [],

View File

@@ -1,7 +1,7 @@
# Prysm: An Ethereum 2.0 Client Written in Go
[![Build status](https://badge.buildkite.com/b555891daf3614bae4284dcf365b2340cefc0089839526f096.svg?branch=master)](https://buildkite.com/prysmatic-labs/prysm)
[![ETH2.0_Spec_Version 0.12.2](https://img.shields.io/badge/ETH2.0%20Spec%20Version-v0.12.2-blue.svg)](https://github.com/ethereum/eth2.0-specs/tree/v0.12.2)
[![ETH2.0_Spec_Version 0.12.3](https://img.shields.io/badge/ETH2.0%20Spec%20Version-v0.12.3-blue.svg)](https://github.com/ethereum/eth2.0-specs/tree/v0.12.3)
[![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/geth-sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

45
TERMS_OF_SERVICE.md Normal file
View File

@@ -0,0 +1,45 @@
## Terms of Use
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.
### Licensing Terms
Prysm is a fully open-source software program licensed pursuant to the GNU General Public License v3.0.
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.
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.
We make no claims that Prysm is appropriate or permitted for use in any specific jurisdiction. Access to Prysm may not be legal by certain persons or in certain jurisdictions or countries. If you access Prysm, you do so on your own initiative and are responsible for compliance with local laws.
Some Internet plans will charge an additional amount for any excess upload bandwidth used that isnt included in the plan and may terminate your connection without warning because of overuse. We advise that you check whether your Internet connection is subjected to such limitations and monitor your bandwidth use so that you can stop Prysm before you reach your upload limit.
### Warranty Disclaimer
PRYSM IS PROVIDED ON AN “AS-IS” BASIS AND MAY INCLUDE ERRORS, OMISSIONS, OR OTHER INACCURACIES. PRYSMATIC LABS AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT PRYSM FOR ANY PURPOSE, AND HEREBY EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT OR ANY OTHER IMPLIED WARRANTY UNDER THE UNIFORM COMPUTER INFORMATION TRANSACTIONS ACT AS ENACTED BY ANY STATE. WE ALSO MAKE NO REPRESENTATIONS OR WARRANTIES THAT PRYSM WILL OPERATE ERROR-FREE, UNINTERRUPTED, OR IN A MANNER THAT WILL MEET YOUR REQUIREMENTS AND/OR NEEDS. THEREFORE, YOU ASSUME THE ENTIRE RISK REGARDING THE QUALITY AND/OR PERFORMANCE OF PRYSM AND ANY TRANSACTIONS ENTERED INTO THEREON.
### Limitation of Liability
In no event will Prysmatic Labs or any of its contributors be liable, whether in contract, warranty, tort (including negligence, whether active, passive or imputed), product liability, strict liability or other theory, breach of statutory duty or otherwise arising out of, or in connection with, your use of Prysm, for any direct, indirect, incidental, special or consequential damages (including any loss of profits or data, business interruption or other pecuniary loss, or damage, loss or other compromise of data, in each case whether direct, indirect, incidental, special or consequential) arising out of use Prysm, even if we or other users have been advised of the possibility of such damages. The foregoing limitations and disclaimers shall apply to the maximum extent permitted by applicable law, even if any remedy fails of its essential purpose. You acknowledge and agree that the limitations of liability afforded us hereunder constitute a material and actual inducement and condition to entering into these Terms, and are reasonable, fair and equitable in scope to protect our legitimate interests in light of the fact that we are not receiving consideration from you for providing Prysm.
### Indemnification
To the maximum extent permitted by law, you will defend, indemnify and hold Prysmatic Labs and its contributors harmless from and against any and all claims, actions, suits, investigations, or proceedings by any third party (including any party or purported party to or beneficiary or purported beneficiary of any transaction on Prysm), as well as any and all losses, liabilities,
damages, costs, and expenses (including reasonable attorneys fees) arising out of, accruing from, or in any way related to (i) your breach of the terms of this Agreement, (ii) any transaction, or the failure to occur of any transaction on Prysm, and (iii) your negligence, fraud, or willful misconduct.
### Compliance with Laws and Tax Obligations
Your use of Prysm is subject to all applicable laws of any governmental authority, including, without limitation, federal, state and foreign securities laws, tax laws, tariff and trade laws, ordinances, judgments, decrees, injunctions, writs and orders or like actions of any governmental authority and rules, regulations, orders, interpretations, licenses, and permits of any federal,
regional, state, county, municipal or other governmental authority and you agree to comply with all such laws in your use of Prysm. The users of Prysm are solely responsible to determinate what, if any, taxes apply to their ETH transactions. The owners of, or contributors to, Prysm are not responsible for determining the taxes that apply to ETH transactions.
### Miscellaneous
These Terms will be construed and enforced in accordance with the laws of the state of Illinois as applied to agreements entered into and completely performed in Illinois. You agree to the personal jurisdiction by and venue in Illinois and waive any objection to such jurisdiction or venue.
We reserve the right to revise these Terms, and your rights and obligations are at all times subject to the then-current Terms provided on Prysm. Your continued use of Prysm constitutes acceptance of such revised Terms.
These Terms constitute the entire agreement between you and Prysmatic Labs regarding use of Prysm and will supersede all prior agreements whether, written or oral. No usage of trade or other regular practice or method of dealing between the parties will be used to modify, interpret, supplement, or alter the terms of these Terms.
If any portion of these Terms is held invalid or unenforceable, such invalidity or enforceability will not affect the other provisions of these Terms, which will remain in full force and effect, and the invalid or unenforceable portion will be given effect to the greatest extent possible. The failure of a party to require performance of any provision will not affect that partys right to require performance at any time thereafter, nor will a waiver of any breach or default of these Terms or any provision of these Terms constitute a waiver of any subsequent breach or default or a waiver of the provision itself.

View File

@@ -5,11 +5,11 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
http_archive(
name = "bazel_toolchains",
sha256 = "144290c4166bd67e76a54f96cd504ed86416ca3ca82030282760f0823c10be48",
strip_prefix = "bazel-toolchains-3.1.1",
sha256 = "db48eed61552e25d36fe051a65d2a329cc0fb08442627e8f13960c5ab087a44e",
strip_prefix = "bazel-toolchains-3.2.0",
urls = [
"https://github.com/bazelbuild/bazel-toolchains/releases/download/3.1.1/bazel-toolchains-3.1.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/3.1.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/releases/download/3.2.0/bazel-toolchains-3.2.0.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/releases/download/3.2.0/bazel-toolchains-3.2.0.tar.gz",
],
)
@@ -161,6 +161,10 @@ 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()
@@ -215,8 +219,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "9e09ada15c5f494388ecdb3ab49f4554d9ed53ce904cd21c42c350e6d7b2f323",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.2/general.tar.gz",
sha256 = "6b3498001de98c477aa2c256beffc20a85ce1b12b8e0f8e88502a5c3a18c01de",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0-rc.0/general.tar.gz",
)
http_archive(
@@ -231,8 +235,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "5fc930e200af7682a176d6025db56cec79807112bb860dca2e1e91fb160312de",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.2/minimal.tar.gz",
sha256 = "72c2f561db879ddcdf729fef93d10e0f9162b4cf3a697c513ef8935b93f6165a",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.3/minimal.tar.gz",
)
http_archive(
@@ -247,8 +251,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "fbab14605a0178ef4c8f7efea0de275a22b815a8d3245099f0f5525f7a33faf8",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.2/mainnet.tar.gz",
sha256 = "63eca02503692a0b6a2d7b70118e0dd62dff094153a3a542af6dbea721841b0d",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.3/mainnet.tar.gz",
)
http_archive(
@@ -336,6 +340,21 @@ go_binary(
urls = ["https://github.com/ferranbt/fastssz/archive/06015a5d84f9e4eefe2c21377ca678fa8f1a1b09.tar.gz"],
)
http_archive(
name = "prysm_web_ui",
build_file_content = """
filegroup(
name = "site",
srcs = glob(["**/*"]),
visibility = ["//visibility:public"],
)
""",
sha256 = "6bb16ff0dc9348090cc31a9ea453643d32b617e66ac6e7bb38985d530070631b",
urls = [
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/0.0.2-alpha/prysm-web-ui.tar.gz",
],
)
load("//:deps.bzl", "prysm_deps")
# gazelle:repository_macro deps.bzl%prysm_deps

View File

@@ -19,15 +19,16 @@ go_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_urfave_cli_v2//altsrc:go_default_library",
"@com_github_x_cray_logrus_prefixed_formatter//:go_default_library",
],
)
@@ -53,19 +54,20 @@ go_image(
deps = [
"//beacon-chain/flags:go_default_library",
"//beacon-chain/node:go_default_library",
"//shared/tos: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/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_urfave_cli_v2//altsrc:go_default_library",
"@com_github_x_cray_logrus_prefixed_formatter//:go_default_library",
"//shared/maxprocs:go_default_library",
],
)

View File

@@ -17,9 +17,13 @@ go_library(
"receive_attestation.go",
"receive_block.go",
"service.go",
"weak_subjectivity_checks.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/blockchain",
visibility = ["//beacon-chain:__subpackages__"],
visibility = [
"//beacon-chain:__subpackages__",
"//fuzz:__pkg__",
],
deps = [
"//beacon-chain/cache:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
@@ -30,6 +34,7 @@ go_library(
"//beacon-chain/core/helpers:go_default_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",
@@ -40,15 +45,14 @@ go_library(
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/params:go_default_library",
"//shared/roughtime:go_default_library",
"//shared/slotutil:go_default_library",
"//shared/timeutils:go_default_library",
"//shared/traceutil:go_default_library",
"@com_github_emicklei_dot//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
@@ -75,11 +79,13 @@ go_test(
"chain_info_test.go",
"head_test.go",
"info_test.go",
"metrics_test.go",
"process_attestation_test.go",
"process_block_test.go",
"receive_attestation_test.go",
"receive_block_test.go",
"service_test.go",
"weak_subjectivity_checks_test.go",
],
embed = [":go_default_library"],
deps = [

View File

@@ -5,14 +5,14 @@ import (
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"go.opencensus.io/trace"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
// ChainInfoFetcher defines a common interface for methods in blockchain service which
@@ -97,6 +97,9 @@ func (s *Service) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
// HeadSlot returns the slot of the head of the chain.
func (s *Service) HeadSlot() uint64 {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return 0
}
@@ -106,6 +109,9 @@ func (s *Service) HeadSlot() uint64 {
// HeadRoot returns the root of the head of the chain.
func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if s.headRoot() != params.BeaconConfig().ZeroHash {
r := s.headRoot()
return r[:], nil
@@ -119,7 +125,7 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
return params.BeaconConfig().ZeroHash[:], nil
}
r, err := stateutil.BlockRoot(b.Block)
r, err := b.Block.HashTreeRoot()
if err != nil {
return nil, err
}
@@ -131,6 +137,9 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
// 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) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if s.hasHeadState() {
return s.headBlock(), nil
}
@@ -144,6 +153,8 @@ func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, erro
func (s *Service) HeadState(ctx context.Context) (*state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.HeadState")
defer span.End()
s.headLock.RLock()
defer s.headLock.RUnlock()
ok := s.hasHeadState()
span.AddAttributes(trace.BoolAttribute("cache_hit", ok))
@@ -152,11 +163,14 @@ func (s *Service) HeadState(ctx context.Context) (*state.BeaconState, error) {
return s.headState(ctx), nil
}
return s.beaconDB.HeadState(ctx)
return s.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) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return []uint64{}, nil
}
@@ -165,6 +179,9 @@ func (s *Service) HeadValidatorsIndices(ctx context.Context, epoch uint64) ([]ui
// HeadSeed returns the seed from the head view of a given epoch.
func (s *Service) HeadSeed(ctx context.Context, epoch uint64) ([32]byte, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return [32]byte{}, nil
}
@@ -174,6 +191,9 @@ func (s *Service) HeadSeed(ctx context.Context, epoch uint64) ([32]byte, error)
// HeadGenesisValidatorRoot returns genesis validator root of the head state.
func (s *Service) HeadGenesisValidatorRoot() [32]byte {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return [32]byte{}
}
@@ -183,6 +203,9 @@ func (s *Service) HeadGenesisValidatorRoot() [32]byte {
// HeadETH1Data returns the eth1data of the current head state.
func (s *Service) HeadETH1Data() *ethpb.Eth1Data {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return &ethpb.Eth1Data{}
}
@@ -202,6 +225,9 @@ func (s *Service) GenesisTime() time.Time {
// GenesisValidatorRoot returns the genesis validator
// root of the chain.
func (s *Service) GenesisValidatorRoot() [32]byte {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return [32]byte{}
}
@@ -210,6 +236,9 @@ func (s *Service) GenesisValidatorRoot() [32]byte {
// CurrentFork retrieves the latest fork information of the beacon chain.
func (s *Service) CurrentFork() *pb.Fork {
s.headLock.RLock()
defer s.headLock.RUnlock()
if !s.hasHeadState() {
return &pb.Fork{
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
@@ -226,9 +255,6 @@ func (s *Service) IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, er
return true, nil
}
// If the block has not been finalized, the block must be recent. Check recent canonical roots
// mapping which uses proto array fork choice.
s.recentCanonicalBlocksLock.RLock()
defer s.recentCanonicalBlocksLock.RUnlock()
return s.recentCanonicalBlocks[blockRoot], 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
}

View File

@@ -1,7 +1,6 @@
package blockchain
import (
"bytes"
"context"
"testing"
"time"
@@ -11,22 +10,22 @@ import (
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
)
// Ensure Service implements chain info interface.
var _ = ChainInfoFetcher(&Service{})
var _ = TimeFetcher(&Service{})
var _ = ForkFetcher(&Service{})
var _ ChainInfoFetcher = (*Service)(nil)
var _ TimeFetcher = (*Service)(nil)
var _ ForkFetcher = (*Service)(nil)
func TestFinalizedCheckpt_Nil(t *testing.T) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
if !bytes.Equal(c.FinalizedCheckpt().Root, params.BeaconConfig().ZeroHash[:]) {
t.Error("Incorrect pre chain start value")
}
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], c.FinalizedCheckpt().Root, "Incorrect pre chain start value")
}
func TestHeadRoot_Nil(t *testing.T) {
@@ -34,15 +33,13 @@ func TestHeadRoot_Nil(t *testing.T) {
c := setupBeaconChain(t, db, sc)
headRoot, err := c.HeadRoot(context.Background())
require.NoError(t, err)
if !bytes.Equal(headRoot, params.BeaconConfig().ZeroHash[:]) {
t.Error("Incorrect pre chain start value")
}
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], headRoot, "Incorrect pre chain start value")
}
func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
cp := &ethpb.Checkpoint{Epoch: 5, Root: []byte("foo")}
cp := &ethpb.Checkpoint{Epoch: 5, Root: bytesutil.PadTo([]byte("foo"), 32)}
c := setupBeaconChain(t, db, sc)
c.finalizedCheckpt = cp
@@ -57,16 +54,13 @@ func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
c := setupBeaconChain(t, db, sc)
c.finalizedCheckpt = cp
c.genesisRoot = genesisRoot
if !bytes.Equal(c.FinalizedCheckpt().Root, c.genesisRoot[:]) {
t.Errorf("Got: %v, wanted: %v", c.FinalizedCheckpt().Root, c.genesisRoot[:])
}
assert.DeepEqual(t, c.genesisRoot[:], c.FinalizedCheckpt().Root)
}
func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
cp := &ethpb.Checkpoint{Epoch: 6, Root: []byte("foo")}
cp := &ethpb.Checkpoint{Epoch: 6, Root: bytesutil.PadTo([]byte("foo"), 32)}
c := setupBeaconChain(t, db, sc)
c.justifiedCheckpt = cp
@@ -81,19 +75,15 @@ func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
c := setupBeaconChain(t, db, sc)
c.justifiedCheckpt = cp
c.genesisRoot = genesisRoot
if !bytes.Equal(c.CurrentJustifiedCheckpt().Root, c.genesisRoot[:]) {
t.Errorf("Got: %v, wanted: %v", c.CurrentJustifiedCheckpt().Root, c.genesisRoot[:])
}
assert.DeepEqual(t, c.genesisRoot[:], c.CurrentJustifiedCheckpt().Root)
}
func TestPreviousJustifiedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
cp := &ethpb.Checkpoint{Epoch: 7, Root: []byte("foo")}
cp := &ethpb.Checkpoint{Epoch: 7, Root: bytesutil.PadTo([]byte("foo"), 32)}
c := setupBeaconChain(t, db, sc)
c.prevJustifiedCheckpt = cp
assert.Equal(t, cp.Epoch, c.PreviousJustifiedCheckpt().Epoch, "Unexpected previous justified epoch")
}
@@ -105,30 +95,28 @@ func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
c := setupBeaconChain(t, db, sc)
c.prevJustifiedCheckpt = cp
c.genesisRoot = genesisRoot
if !bytes.Equal(c.PreviousJustifiedCheckpt().Root, c.genesisRoot[:]) {
t.Errorf("Got: %v, wanted: %v", c.PreviousJustifiedCheckpt().Root, c.genesisRoot[:])
}
assert.DeepEqual(t, c.genesisRoot[:], c.PreviousJustifiedCheckpt().Root)
}
func TestHeadSlot_CanRetrieve(t *testing.T) {
c := &Service{}
s, err := state.InitializeFromProto(&pb.BeaconState{})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c.head = &head{slot: 100, state: s}
assert.Equal(t, uint64(100), c.headSlot())
assert.Equal(t, uint64(100), c.HeadSlot())
}
func TestHeadRoot_CanRetrieve(t *testing.T) {
c := &Service{}
c.head = &head{root: [32]byte{'A'}}
assert.Equal(t, [32]byte{'A'}, c.headRoot())
r, err := c.HeadRoot(context.Background())
require.NoError(t, err)
assert.Equal(t, [32]byte{'A'}, bytesutil.ToBytes32(r))
}
func TestHeadBlock_CanRetrieve(t *testing.T) {
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 1}}
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
s, err := state.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c := &Service{}
@@ -146,9 +134,7 @@ func TestHeadState_CanRetrieve(t *testing.T) {
c.head = &head{state: s}
headState, err := c.HeadState(context.Background())
require.NoError(t, err)
if !proto.Equal(s.InnerStateUnsafe(), headState.InnerStateUnsafe()) {
t.Error("incorrect head state received")
}
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Incorrect head state received")
}
func TestGenesisTime_CanRetrieve(t *testing.T) {
@@ -195,3 +181,23 @@ func TestHeadETH1Data_CanRetrieve(t *testing.T) {
t.Error("Received incorrect eth1 data")
}
}
func TestIsCanonical_Ok(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
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))
can, err := c.IsCanonical(ctx, root)
require.NoError(t, err)
assert.Equal(t, true, can)
can, err = c.IsCanonical(ctx, [32]byte{'a'})
require.NoError(t, err)
assert.Equal(t, false, can)
}

View File

@@ -11,7 +11,6 @@ import (
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -24,7 +23,7 @@ type head struct {
slot uint64 // current head slot.
root [32]byte // current head root.
block *ethpb.SignedBeaconBlock // current head block.
state *state.BeaconState // current head state.
state *stateTrie.BeaconState // current head state.
}
// Determined the head from the fork choice service and saves its new data
@@ -52,12 +51,24 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
if headStartRoot == params.BeaconConfig().ZeroHash {
headStartRoot = s.genesisRoot
}
headRoot, err := s.forkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
if err != nil {
return err
// In order to process head, fork choice store requires justified info.
// 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 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 {
return err
}
}
if err := s.updateRecentCanonicalBlocks(ctx, headRoot); err != nil {
headRoot, err := s.forkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
if err != nil {
return err
}
@@ -72,7 +83,11 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
defer span.End()
// Do nothing if head hasn't changed.
if headRoot == s.headRoot() {
r, err := s.HeadRoot(ctx)
if err != nil {
return err
}
if headRoot == bytesutil.ToBytes32(r) {
return nil
}
@@ -101,16 +116,17 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
}
// A chain re-org occurred, so we fire an event notifying the rest of the services.
if bytesutil.ToBytes32(newHeadBlock.Block.ParentRoot) != s.headRoot() {
headSlot := s.HeadSlot()
if bytesutil.ToBytes32(newHeadBlock.Block.ParentRoot) != bytesutil.ToBytes32(r) {
log.WithFields(logrus.Fields{
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block.Slot),
"oldSlot": fmt.Sprintf("%d", s.headSlot()),
"oldSlot": fmt.Sprintf("%d", headSlot),
}).Debug("Chain reorg occurred")
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Reorg,
Data: &statefeed.ReorgData{
NewSlot: newHeadBlock.Block.Slot,
OldSlot: s.headSlot(),
OldSlot: headSlot,
},
})
@@ -131,7 +147,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// 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 *state.BeaconState) error {
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs *stateTrie.BeaconState) error {
cachedHeadRoot, err := s.HeadRoot(ctx)
if err != nil {
return errors.Wrap(err, "could not get head root from cache")
@@ -149,7 +165,7 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
}
// 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 *state.BeaconState) {
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
@@ -165,7 +181,7 @@ 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 *state.BeaconState) {
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
@@ -179,89 +195,57 @@ func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlo
}
// This returns the head slot.
// This is a lock free version.
func (s *Service) headSlot() uint64 {
s.headLock.RLock()
defer s.headLock.RUnlock()
return s.head.slot
}
// This returns the head root.
// It does a full copy on head root for immutability.
// This is a lock free version.
func (s *Service) headRoot() [32]byte {
if s.head == nil {
return params.BeaconConfig().ZeroHash
}
s.headLock.RLock()
defer s.headLock.RUnlock()
return s.head.root
}
// 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 {
s.headLock.RLock()
defer s.headLock.RUnlock()
return stateTrie.CopySignedBeaconBlock(s.head.block)
}
// 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 {
ctx, span := trace.StartSpan(ctx, "blockChain.headState")
defer span.End()
s.headLock.RLock()
defer s.headLock.RUnlock()
return s.head.state.Copy()
}
// This returns the genesis validator root of the head state.
// This is a lock free version.
func (s *Service) headGenesisValidatorRoot() [32]byte {
s.headLock.RLock()
defer s.headLock.RUnlock()
return bytesutil.ToBytes32(s.head.state.GenesisValidatorRoot())
}
// Returns true if head state exists.
func (s *Service) hasHeadState() bool {
// HasHeadState returns true if head state exists.
func (s *Service) HasHeadState() bool {
s.headLock.RLock()
defer s.headLock.RUnlock()
return s.head != nil && s.head.state != nil
return s.hasHeadState()
}
// This updates recent canonical block mapping. It uses input head root and retrieves
// all the canonical block roots that are ancestor of the input head block root.
func (s *Service) updateRecentCanonicalBlocks(ctx context.Context, headRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.updateRecentCanonicalBlocks")
defer span.End()
s.recentCanonicalBlocksLock.Lock()
defer s.recentCanonicalBlocksLock.Unlock()
s.recentCanonicalBlocks = make(map[[32]byte]bool)
s.recentCanonicalBlocks[headRoot] = true
nodes := s.forkChoiceStore.Nodes()
node := s.forkChoiceStore.Node(headRoot)
if node == nil {
return nil
}
for node.Parent() != protoarray.NonExistentNode {
if ctx.Err() != nil {
return ctx.Err()
}
node = nodes[node.Parent()]
s.recentCanonicalBlocks[node.Root()] = true
}
return nil
// Returns true if head state exists.
// This is the lock free version.
func (s *Service) hasHeadState() bool {
return s.head != nil && s.head.state != nil
}
// This caches justified state balances to be used for fork choice.

View File

@@ -7,7 +7,6 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -35,11 +34,12 @@ func TestSaveHead_Different(t *testing.T) {
oldRoot := [32]byte{'A'}
service.head = &head{slot: 0, root: oldRoot}
newHeadBlock := &ethpb.BeaconBlock{Slot: 1}
newHeadSignedBlock := &ethpb.SignedBeaconBlock{Block: newHeadBlock}
newHeadSignedBlock := testutil.NewBeaconBlock()
newHeadSignedBlock.Block.Slot = 1
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := stateutil.BlockRoot(newHeadBlock)
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
require.NoError(t, headState.SetSlot(1))
@@ -68,14 +68,13 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
service.head = &head{slot: 0, root: oldRoot}
reorgChainParent := [32]byte{'B'}
newHeadBlock := &ethpb.BeaconBlock{
Slot: 1,
ParentRoot: reorgChainParent[:],
}
newHeadSignedBlock := &ethpb.SignedBeaconBlock{Block: newHeadBlock}
newHeadSignedBlock := testutil.NewBeaconBlock()
newHeadSignedBlock.Block.Slot = 1
newHeadSignedBlock.Block.ParentRoot = reorgChainParent[:]
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := stateutil.BlockRoot(newHeadBlock)
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
require.NoError(t, headState.SetSlot(1))
@@ -95,39 +94,6 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
require.LogsContain(t, hook, "Chain reorg occurred")
}
func TestUpdateRecentCanonicalBlocks_CanUpdateWithoutParent(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
r := [32]byte{'a'}
require.NoError(t, service.updateRecentCanonicalBlocks(context.Background(), r))
canonical, err := service.IsCanonical(context.Background(), r)
require.NoError(t, err)
assert.Equal(t, true, canonical, "Block should be canonical")
}
func TestUpdateRecentCanonicalBlocks_CanUpdateWithParent(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
oldHead := [32]byte{'a'}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 1, oldHead, [32]byte{'g'}, [32]byte{}, 0, 0))
currentHead := [32]byte{'b'}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 3, currentHead, oldHead, [32]byte{}, 0, 0))
forkedRoot := [32]byte{'c'}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 2, forkedRoot, oldHead, [32]byte{}, 0, 0))
require.NoError(t, service.updateRecentCanonicalBlocks(context.Background(), currentHead))
canonical, err := service.IsCanonical(context.Background(), currentHead)
require.NoError(t, err)
assert.Equal(t, true, canonical, "Block should be canonical")
canonical, err = service.IsCanonical(context.Background(), oldHead)
require.NoError(t, err)
assert.Equal(t, true, canonical, "Block should be canonical")
canonical, err = service.IsCanonical(context.Background(), forkedRoot)
require.NoError(t, err)
assert.Equal(t, false, canonical, "Block should not be canonical")
}
func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
db, sc := testDB.SetupDB(t)
service := setupBeaconChain(t, db, sc)
@@ -139,3 +105,19 @@ func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
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)
b := testutil.NewBeaconBlock()
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.finalizedCheckpt = &ethpb.Checkpoint{}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, service.updateHead(context.Background(), []uint64{}))
}

View File

@@ -34,7 +34,12 @@ const template = `<html>
// TreeHandler is a handler to serve /tree page in metrics.
func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
if s.headState(r.Context()) == nil {
headState, err := s.HeadState(r.Context())
if err != nil {
log.WithError(err).Error("Could not get head state")
return
}
if headState == nil {
if _, err := w.Write([]byte("Unavailable during initial syncing")); err != nil {
log.WithError(err).Error("Failed to render p2p info page")
}
@@ -47,7 +52,7 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
graph.Attr("labeljust", "l")
dotNodes := make([]*dot.Node, len(nodes))
avgBalance := uint64(averageBalance(s.headState(r.Context()).Balances()))
avgBalance := uint64(averageBalance(headState.Balances()))
for i := len(nodes) - 1; i >= 0; i-- {
// Construct label for each node.
@@ -63,7 +68,7 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
dotN = graph.Node(index).Box().Attr("label", label)
}
if nodes[i].Slot() == s.headSlot() &&
if nodes[i].Slot() == s.HeadSlot() &&
nodes[i].BestDescendant() == ^uint64(0) &&
nodes[i].Parent() != ^uint64(0) {
dotN = dotN.Attr("color", "green")

View File

@@ -33,6 +33,7 @@ func TestService_TreeHandler(t *testing.T) {
StateGen: stategen.New(db, sCache),
}
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)

View File

@@ -6,6 +6,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
)
@@ -25,9 +26,10 @@ func logStateTransitionData(b *ethpb.BeaconBlock) {
func logBlockSyncStatus(block *ethpb.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint) {
log.WithFields(logrus.Fields{
"slot": block.Slot,
"slotInEpoch": block.Slot % params.BeaconConfig().SlotsPerEpoch,
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"epoch": helpers.SlotToEpoch(block.Slot),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root[:])[:8]),
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
}).Info("Synced new block")
}

View File

@@ -1,17 +1,15 @@
package blockchain
import (
"time"
"context"
"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/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
)
var (
@@ -76,25 +74,30 @@ var (
Name: "current_eth1_data_deposit_count",
Help: "The current eth1 deposit count in the last processed state eth1data field.",
})
totalEligibleBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "total_eligible_balances",
Help: "The total amount of ether, in gwei, that is eligible for voting of previous epoch",
stateTrieReferences = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "field_references",
Help: "The number of states a particular field is shared with.",
}, []string{"state"})
prevEpochActiveBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "beacon_prev_epoch_active_gwei",
Help: "The total amount of ether, in gwei, that was active for voting of previous epoch",
})
totalVotedTargetBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "total_voted_target_balances",
prevEpochSourceBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "beacon_prev_epoch_source_gwei",
Help: "The total amount of ether, in gwei, that has been used in voting attestation source of previous epoch",
})
prevEpochTargetBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "beacon_prev_epoch_target_gwei",
Help: "The total amount of ether, in gwei, that has been used in voting attestation target of previous epoch",
})
prevEpochHeadBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "beacon_prev_epoch_head_gwei",
Help: "The total amount of ether, in gwei, that has been used in voting attestation head of previous epoch",
})
reorgCount = promauto.NewCounter(prometheus.CounterOpts{
Name: "beacon_reorg_total",
Help: "Count the number of times beacon chain has a reorg",
})
sentBlockPropagationHistogram = promauto.NewHistogram(
prometheus.HistogramOpts{
Name: "block_sent_latency_milliseconds",
Help: "Captures blocks broadcast time. Blocks sent in milliseconds distribution",
Buckets: []float64{1000, 2000, 3000, 4000, 5000, 6000},
},
)
attestationInclusionDelay = promauto.NewHistogram(
prometheus.HistogramOpts{
Name: "attestation_inclusion_delay_slots",
@@ -105,7 +108,7 @@ var (
)
// reportSlotMetrics reports slot related metrics.
func reportSlotMetrics(stateSlot uint64, headSlot uint64, clockSlot uint64, finalizedCheckpoint *ethpb.Checkpoint) {
func reportSlotMetrics(stateSlot, headSlot, clockSlot uint64, finalizedCheckpoint *ethpb.Checkpoint) {
clockTimeSlot.Set(float64(clockSlot))
beaconSlot.Set(float64(stateSlot))
beaconHeadSlot.Set(float64(headSlot))
@@ -116,8 +119,8 @@ func reportSlotMetrics(stateSlot uint64, headSlot uint64, clockSlot uint64, fina
}
// reportEpochMetrics reports epoch related metrics.
func reportEpochMetrics(state *stateTrie.BeaconState) {
currentEpoch := state.Slot() / params.BeaconConfig().SlotsPerEpoch
func reportEpochMetrics(ctx context.Context, postState, headState *stateTrie.BeaconState) error {
currentEpoch := postState.Slot() / params.BeaconConfig().SlotsPerEpoch
// Validator instances
pendingInstances := 0
@@ -135,8 +138,8 @@ func reportEpochMetrics(state *stateTrie.BeaconState) {
slashingBalance := uint64(0)
slashingEffectiveBalance := uint64(0)
for i, validator := range state.Validators() {
bal, err := state.BalanceAtIndex(uint64(i))
for i, validator := range postState.Validators() {
bal, err := postState.BalanceAtIndex(uint64(i))
if err != nil {
log.Errorf("Could not load validator balance: %v", err)
continue
@@ -185,33 +188,36 @@ func reportEpochMetrics(state *stateTrie.BeaconState) {
validatorsEffectiveBalance.WithLabelValues("Slashing").Set(float64(slashingEffectiveBalance))
// Last justified slot
beaconCurrentJustifiedEpoch.Set(float64(state.CurrentJustifiedCheckpoint().Epoch))
beaconCurrentJustifiedRoot.Set(float64(bytesutil.ToLowInt64(state.CurrentJustifiedCheckpoint().Root)))
beaconCurrentJustifiedEpoch.Set(float64(postState.CurrentJustifiedCheckpoint().Epoch))
beaconCurrentJustifiedRoot.Set(float64(bytesutil.ToLowInt64(postState.CurrentJustifiedCheckpoint().Root)))
// Last previous justified slot
beaconPrevJustifiedEpoch.Set(float64(state.PreviousJustifiedCheckpoint().Epoch))
beaconPrevJustifiedRoot.Set(float64(bytesutil.ToLowInt64(state.PreviousJustifiedCheckpoint().Root)))
beaconPrevJustifiedEpoch.Set(float64(postState.PreviousJustifiedCheckpoint().Epoch))
beaconPrevJustifiedRoot.Set(float64(bytesutil.ToLowInt64(postState.PreviousJustifiedCheckpoint().Root)))
// Last finalized slot
beaconFinalizedEpoch.Set(float64(state.FinalizedCheckpointEpoch()))
beaconFinalizedRoot.Set(float64(bytesutil.ToLowInt64(state.FinalizedCheckpoint().Root)))
beaconFinalizedEpoch.Set(float64(postState.FinalizedCheckpointEpoch()))
beaconFinalizedRoot.Set(float64(bytesutil.ToLowInt64(postState.FinalizedCheckpoint().Root)))
currentEth1DataDepositCount.Set(float64(postState.Eth1Data().DepositCount))
currentEth1DataDepositCount.Set(float64(state.Eth1Data().DepositCount))
if precompute.Balances != nil {
totalEligibleBalances.Set(float64(precompute.Balances.ActivePrevEpoch))
totalVotedTargetBalances.Set(float64(precompute.Balances.PrevEpochTargetAttested))
}
}
// This captures metrics for block sent time by subtracts slot start time.
func captureSentTimeMetric(genesisTime uint64, currentSlot uint64) error {
startTime, err := helpers.SlotToTime(genesisTime, currentSlot)
// Validator participation should be viewed on the canonical chain.
v, b, err := precompute.New(ctx, headState)
if err != nil {
return err
}
diffMs := roughtime.Now().Sub(startTime) / time.Millisecond
sentBlockPropagationHistogram.Observe(float64(diffMs))
_, b, err = precompute.ProcessAttestations(ctx, headState, v, b)
if err != nil {
return err
}
prevEpochActiveBalances.Set(float64(b.ActivePrevEpoch))
prevEpochSourceBalances.Set(float64(b.PrevEpochAttested))
prevEpochTargetBalances.Set(float64(b.PrevEpochTargetAttested))
prevEpochHeadBalances.Set(float64(b.PrevEpochHeadAttested))
refMap := postState.FieldReferencesCount()
for name, val := range refMap {
stateTrieReferences.WithLabelValues(name).Set(float64(val))
}
return nil
}

View File

@@ -0,0 +1,26 @@
package blockchain
import (
"context"
"testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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()
require.NoError(t, h.SetValidators(nil))
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)
require.ErrorContains(t, "attestation with inclusion delay of 0", err)
}

View File

@@ -10,7 +10,7 @@ import (
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"go.opencensus.io/trace"
)
@@ -73,10 +73,10 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]ui
return nil, err
}
genesisTime := helpers.GenesisTime(baseState)
genesisTime := baseState.GenesisTime()
// Verify attestation target is from current epoch or previous epoch.
if err := s.verifyAttTargetEpoch(ctx, genesisTime, uint64(roughtime.Now().Unix()), tgt); err != nil {
if err := s.verifyAttTargetEpoch(ctx, genesisTime, uint64(timeutils.Now().Unix()), tgt); err != nil {
return nil, err
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
@@ -18,10 +19,7 @@ import (
// 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) {
s.checkpointStateLock.Lock()
defer s.checkpointStateLock.Unlock()
cachedState, err := s.checkpointState.StateByCheckpoint(c)
cachedState, err := s.checkpointStateCache.StateByCheckpoint(ctx, c)
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
}
@@ -29,38 +27,59 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
return cachedState, nil
}
if err := s.checkpointStateCache.MarkInProgress(c); err != nil {
if errors.Is(err, cache.ErrAlreadyInProgress) {
cachedState, err = s.checkpointStateCache.StateByCheckpoint(ctx, c)
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
}
if cachedState != nil {
return cachedState, nil
}
} else {
return nil, err
}
}
defer func() {
if err := s.checkpointStateCache.MarkNotInProgress(c); err != nil {
log.WithError(err).Error("Failed to mark cache not in progress")
}
}()
baseState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", helpers.StartSlot(c.Epoch))
return nil, errors.Wrapf(err, "could not get pre state for epoch %d", c.Epoch)
}
if helpers.StartSlot(c.Epoch) > baseState.Slot() {
baseState = baseState.Copy()
baseState, err = state.ProcessSlots(ctx, baseState, helpers.StartSlot(c.Epoch))
epochStartSlot, err := helpers.StartSlot(c.Epoch)
if err != nil {
return nil, err
}
if epochStartSlot > baseState.Slot() {
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to %d", helpers.StartSlot(c.Epoch))
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
if err := s.checkpointState.AddCheckpointState(c, baseState); err != nil {
if err := s.checkpointStateCache.AddCheckpointState(c, baseState); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
}
return baseState, nil
}
has, err := s.stateGen.HasState(ctx, bytesutil.ToBytes32(c.Root))
// 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))
if err != nil {
return nil, err
}
if !has {
if err := s.checkpointState.AddCheckpointState(c, baseState); err != nil {
if err := s.checkpointStateCache.AddCheckpointState(c, baseState); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
}
}
return baseState, nil
}
// verifyAttTargetEpoch validates attestation is from the current or previous epoch.
func (s *Service) verifyAttTargetEpoch(ctx context.Context, genesisTime uint64, nowTime uint64, c *ethpb.Checkpoint) error {
func (s *Service) verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime uint64, c *ethpb.Checkpoint) error {
currentSlot := (nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot
currentEpoch := helpers.SlotToEpoch(currentSlot)
var prevEpoch uint64
@@ -96,8 +115,11 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
}
// verifyLMDFFGConsistent verifies LMD GHOST and FFG votes are consistent with each other.
func (s *Service) verifyLMDFFGConsistent(ctx context.Context, ffgEpoch uint64, ffgRoot []byte, lmdRoot []byte) error {
ffgSlot := helpers.StartSlot(ffgEpoch)
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

View File

@@ -2,8 +2,9 @@ package blockchain
import (
"context"
"strings"
"sync"
"testing"
"time"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
@@ -11,9 +12,7 @@ import (
"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"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -37,103 +36,95 @@ func TestStore_OnAttestation(t *testing.T) {
_, err = blockTree1(db, []byte{'g'})
require.NoError(t, err)
BlkWithOutState := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 0}}
BlkWithOutState := testutil.NewBeaconBlock()
BlkWithOutState.Block.Slot = 0
require.NoError(t, db.SaveBlock(ctx, BlkWithOutState))
BlkWithOutStateRoot, err := stateutil.BlockRoot(BlkWithOutState.Block)
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
require.NoError(t, err)
BlkWithStateBadAtt := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 1}}
BlkWithStateBadAtt := testutil.NewBeaconBlock()
BlkWithStateBadAtt.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, BlkWithStateBadAtt))
BlkWithStateBadAttRoot, err := stateutil.BlockRoot(BlkWithStateBadAtt.Block)
BlkWithStateBadAttRoot, err := BlkWithStateBadAtt.Block.HashTreeRoot()
require.NoError(t, err)
s := testutil.NewBeaconState()
require.NoError(t, s.SetSlot(100*params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot))
BlkWithValidState := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 2}}
BlkWithValidState := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
require.NoError(t, db.SaveBlock(ctx, BlkWithValidState))
BlkWithValidStateRoot, err := stateutil.BlockRoot(BlkWithValidState.Block)
BlkWithValidStateRoot, err := BlkWithValidState.Block.HashTreeRoot()
require.NoError(t, err)
s = testutil.NewBeaconState()
if err := s.SetFork(&pb.Fork{
err = s.SetFork(&pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
}); err != nil {
t.Fatal(err)
}
})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
tests := []struct {
name string
a *ethpb.Attestation
s *pb.BeaconState
wantErr bool
wantErrString string
name string
a *ethpb.Attestation
wantedErr string
}{
{
name: "attestation's data slot not aligned with target vote",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Slot: params.BeaconConfig().SlotsPerEpoch, Target: &ethpb.Checkpoint{}}},
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "data slot is not in the same epoch as target 1 != 0",
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: []byte{'A'}}}},
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "target root does not exist in db",
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",
},
{
name: "no pre state for attestations's target block",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: BlkWithOutStateRoot[:]}}},
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "could not get pre state for slot 0",
name: "no pre state for attestations's target block",
a: &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[:]}}},
s: &pb.BeaconState{Slot: 100 * params.BeaconConfig().SlotsPerEpoch},
wantErr: true,
wantErrString: "target epoch 100 does not match current epoch",
wantedErr: "target epoch 100 does not match current epoch",
},
{
name: "process nil field (a.Target) in attestation",
a: nil,
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "nil attestation",
name: "process nil attestation",
a: nil,
wantedErr: "nil attestation",
},
{
name: "process nil field (a.Data) in attestation",
a: &ethpb.Attestation{},
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "nil attestation.Data field",
name: "process nil field (a.Data) in attestation",
a: &ethpb.Attestation{},
wantedErr: "nil attestation.Data field",
},
{
name: "process nil field (a.Target) in attestation",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{}},
s: &pb.BeaconState{},
wantErr: true,
wantErrString: "nil attestation.Data.Target field",
name: "process nil field (a.Target) in attestation",
a: &ethpb.Attestation{
Data: &ethpb.AttestationData{
BeaconBlockRoot: make([]byte, 32),
Target: nil,
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
AggregationBits: make([]byte, 1),
Signature: make([]byte, 96),
},
wantedErr: "nil attestation.Data.Target field",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := service.onAttestation(ctx, tt.a)
if tt.wantErr {
if err == nil || !strings.Contains(err.Error(), tt.wantErrString) {
t.Errorf("Store.onAttestation() error = %v, wantErr = %v", err, tt.wantErrString)
}
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
t.Error(err)
assert.NoError(t, err)
}
})
}
@@ -150,22 +141,16 @@ func TestStore_SaveCheckpointState(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Fork: &pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
StateRoots: make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot),
BlockRoots: make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot),
LatestBlockHeader: &ethpb.BeaconBlockHeader{},
JustificationBits: []byte{0},
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
FinalizedCheckpoint: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
Validators: []*ethpb.Validator{{PublicKey: bytesutil.PadTo([]byte("foo"), 48)}},
Balances: []uint64{0},
})
s := testutil.NewBeaconState()
err = s.SetFinalizedCheckpoint(&ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)})
require.NoError(t, err)
val := &ethpb.Validator{
PublicKey: bytesutil.PadTo([]byte("foo"), 48),
WithdrawalCredentials: bytesutil.PadTo([]byte("bar"), 32),
}
err = s.SetValidators([]*ethpb.Validator{val})
require.NoError(t, err)
err = s.SetBalances([]uint64{0})
require.NoError(t, err)
r := [32]byte{'g'}
require.NoError(t, service.beaconDB.SaveState(ctx, s, r))
@@ -195,11 +180,11 @@ func TestStore_SaveCheckpointState(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
s1, err = service.checkpointState.StateByCheckpoint(cp1)
s1, err = service.checkpointStateCache.StateByCheckpoint(ctx, cp1)
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
s2, err = service.checkpointState.StateByCheckpoint(cp2)
s2, err = service.checkpointStateCache.StateByCheckpoint(ctx, cp2)
require.NoError(t, err)
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
@@ -229,33 +214,74 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
epoch := uint64(1)
baseState, _ := testutil.DeterministicGenesisState(t, 1)
require.NoError(t, baseState.SetSlot(epoch*params.BeaconConfig().SlotsPerEpoch))
checkpoint := &ethpb.Checkpoint{Epoch: epoch}
checkpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("hi"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)))
returned, err := service.getAttPreState(ctx, checkpoint)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), baseState.Slot(), "Incorrectly returned base state")
assert.Equal(t, returned.Slot(), checkpoint.Epoch*params.BeaconConfig().SlotsPerEpoch, "Incorrectly returned base state")
cached, err := service.checkpointState.StateByCheckpoint(checkpoint)
cached, err := service.checkpointStateCache.StateByCheckpoint(ctx, checkpoint)
require.NoError(t, err)
assert.NotNil(t, cached, "State should have been cached")
assert.Equal(t, returned.Slot(), cached.Slot(), "State should have been cached")
epoch = uint64(2)
newCheckpoint := &ethpb.Checkpoint{Epoch: epoch}
newCheckpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("bye"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)))
returned, err = service.getAttPreState(ctx, newCheckpoint)
require.NoError(t, err)
baseState, err = state.ProcessSlots(ctx, baseState, helpers.StartSlot(newCheckpoint.Epoch))
s, err := helpers.StartSlot(newCheckpoint.Epoch)
require.NoError(t, err)
baseState, err = state.ProcessSlots(ctx, baseState, s)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), baseState.Slot(), "Incorrectly returned base state")
cached, err = service.checkpointState.StateByCheckpoint(newCheckpoint)
cached, err = service.checkpointStateCache.StateByCheckpoint(ctx, newCheckpoint)
require.NoError(t, err)
if !proto.Equal(returned.InnerStateUnsafe(), cached.InnerStateUnsafe()) {
t.Error("Incorrectly cached base state")
}
}
func TestStore_CheckpointState_InProgress(t *testing.T) {
ctx := context.Background()
db, sc := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
StateGen: stategen.New(db, sc),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
epoch := uint64(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.checkpointStateCache.MarkInProgress(checkpoint))
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
response, err := service.getAttPreState(ctx, checkpoint)
require.NoError(t, err)
if !proto.Equal(baseState.InnerStateUnsafe(), response.InnerStateUnsafe()) {
t.Error("Expected equal responses from cache")
}
}()
wg.Add(1)
go func() {
defer wg.Done()
assert.NoError(t, service.checkpointStateCache.AddCheckpointState(checkpoint, baseState))
assert.NoError(t, service.checkpointStateCache.MarkNotInProgress(checkpoint))
}()
testutil.WaitTimeout(&wg, time.Second*2)
}
func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
@@ -264,13 +290,8 @@ func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
if err := service.verifyAttTargetEpoch(
ctx,
0,
params.BeaconConfig().SlotsPerEpoch*params.BeaconConfig().SecondsPerSlot,
&ethpb.Checkpoint{}); err != nil {
t.Error(err)
}
nowTime := 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) {
@@ -281,13 +302,8 @@ func TestAttEpoch_MatchCurrentEpoch(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
if err := service.verifyAttTargetEpoch(
ctx,
0,
params.BeaconConfig().SlotsPerEpoch*params.BeaconConfig().SecondsPerSlot,
&ethpb.Checkpoint{Epoch: 1}); err != nil {
t.Error(err)
}
nowTime := params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Epoch: 1}))
}
func TestAttEpoch_NotMatch(t *testing.T) {
@@ -298,14 +314,9 @@ func TestAttEpoch_NotMatch(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
if err := service.verifyAttTargetEpoch(
ctx,
0,
2*params.BeaconConfig().SlotsPerEpoch*params.BeaconConfig().SecondsPerSlot,
&ethpb.Checkpoint{}); !strings.Contains(err.Error(),
"target epoch 0 does not match current epoch 2 or prev epoch 1") {
t.Error("Did not receive wanted error")
}
nowTime := 2 * 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) {
@@ -316,8 +327,12 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
d := &ethpb.AttestationData{}
assert.ErrorContains(t, "beacon block does not exist", service.verifyBeaconBlock(ctx, d))
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))
}
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
@@ -328,9 +343,10 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 2}}
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
r, err := stateutil.BlockRoot(b.Block)
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
@@ -345,9 +361,10 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 2}}
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
r, err := stateutil.BlockRoot(b.Block)
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
@@ -362,13 +379,16 @@ func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 32}}
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := stateutil.BlockRoot(b32.Block)
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 33, ParentRoot: r32[:]}}
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := stateutil.BlockRoot(b33.Block)
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
wanted := "FFG and LMD votes are not consistent"
@@ -383,15 +403,102 @@ func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 32}}
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := stateutil.BlockRoot(b32.Block)
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 33, ParentRoot: r32[:]}}
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := stateutil.BlockRoot(b33.Block)
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)
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)
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1}
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.VerifyFinalizedConsistency(context.Background(), r33[:])
require.ErrorContains(t, "Root and finalized store are not consistent", err)
}
func TestVerifyFinalizedConsistency_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)
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1, Root: r32[:]}
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.VerifyFinalizedConsistency(context.Background(), r33[:])
require.NoError(t, err)
}
func TestVerifyFinalizedConsistency_IsCanonical(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
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1, Root: r32[:]}
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
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))
_, err = service.forkChoiceStore.Head(ctx, 0, r32, []uint64{}, 0)
require.NoError(t, err)
err = service.VerifyFinalizedConsistency(context.Background(), r33[:])
require.NoError(t, err)
}

View File

@@ -121,12 +121,26 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
}
// Update deposit cache.
s.depositCache.InsertFinalizedDeposits(ctx, int64(postState.Eth1DepositIndex()))
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")
}
}
}
defer reportAttestationInclusion(b)
return s.handleEpochBoundary(postState)
return s.handleEpochBoundary(ctx, postState)
}
// onBlockInitialSyncStateTransition is called when an initial sync block is received.
@@ -161,12 +175,7 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
return nil
}
var postState *stateTrie.BeaconState
if featureconfig.Get().InitSyncNoVerify {
postState, err = state.ExecuteStateTransitionNoVerifyAttSigs(ctx, preState, signed)
} else {
postState, err = state.ExecuteStateTransition(ctx, preState, signed)
}
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
if err != nil {
return errors.Wrap(err, "could not execute state transition")
}
@@ -200,7 +209,7 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
}
}
return s.handleEpochBoundary(postState)
return s.handleEpochBoundary(ctx, postState)
}
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
@@ -231,11 +240,11 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
jCheckpoints := make([]*ethpb.Checkpoint, len(blks))
fCheckpoints := make([]*ethpb.Checkpoint, len(blks))
sigSet := &bls.SignatureSet{
Signatures: []bls.Signature{},
Signatures: [][]byte{},
PublicKeys: []bls.PublicKey{},
Messages: [][32]byte{},
}
set := new(bls.SignatureSet)
var set *bls.SignatureSet
boundaries := make(map[[32]byte]*stateTrie.BeaconState)
for i, b := range blks {
set, preState, err = state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, b)
@@ -245,15 +254,15 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
// Save potential boundary states.
if helpers.IsEpochStart(preState.Slot()) {
boundaries[blockRoots[i]] = preState.Copy()
if err := s.handleEpochBoundary(preState); err != nil {
return nil, nil, fmt.Errorf("could not handle epoch boundary state")
if err := s.handleEpochBoundary(ctx, preState); err != nil {
return nil, nil, errors.Wrap(err, "could not handle epoch boundary state")
}
}
jCheckpoints[i] = preState.CurrentJustifiedCheckpoint()
fCheckpoints[i] = preState.FinalizedCheckpoint()
sigSet.Join(set)
}
verify, err := bls.VerifyMultipleSignatures(sigSet.Signatures, sigSet.Messages, sigSet.PublicKeys)
verify, err := sigSet.Verify()
if err != nil {
return nil, nil, err
}
@@ -280,7 +289,7 @@ 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,
blockRoot [32]byte, fCheckpoint *ethpb.Checkpoint, jCheckpoint *ethpb.Checkpoint) error {
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
b := signed.Block
s.saveInitSyncBlock(blockRoot, signed)
@@ -313,11 +322,16 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
}
// Epoch boundary bookkeeping such as logging epoch summaries.
func (s *Service) handleEpochBoundary(postState *stateTrie.BeaconState) error {
func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.BeaconState) error {
if postState.Slot() >= s.nextEpochBoundarySlot {
reportEpochMetrics(postState)
s.nextEpochBoundarySlot = helpers.StartSlot(helpers.NextEpoch(postState))
if err := reportEpochMetrics(ctx, postState, s.head.state); err != nil {
return err
}
var err error
s.nextEpochBoundarySlot, err = helpers.StartSlot(helpers.NextEpoch(postState))
if err != nil {
return err
}
// Update committees cache at epoch boundary slot.
if err := helpers.UpdateCommitteeCache(postState, helpers.CurrentEpoch(postState)); err != nil {
return err
@@ -351,7 +365,7 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
}
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock,
root [32]byte, fCheckpoint *ethpb.Checkpoint, jCheckpoint *ethpb.Checkpoint) error {
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
return err
}

View File

@@ -9,30 +9,23 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
)
// CurrentSlot returns the current slot based on time.
func (s *Service) CurrentSlot() uint64 {
now := roughtime.Now().Unix()
genesis := s.genesisTime.Unix()
if now < genesis {
return 0
}
return uint64(now-genesis) / params.BeaconConfig().SecondsPerSlot
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) {
ctx, span := trace.StartSpan(ctx, "forkChoice.getBlockPreState")
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
defer span.End()
// Verify incoming block has a valid pre state.
@@ -49,12 +42,7 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*
}
// Verify block slot time is not from the future.
if err := helpers.VerifySlotTime(helpers.GenesisTime(preState), b.Slot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
}
// Verify block is a descendent of a finalized block.
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot)); err != nil {
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
}
@@ -68,7 +56,7 @@ 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 {
ctx, span := trace.StartSpan(ctx, "chainService.verifyBlkPreState")
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
defer span.End()
parentRoot := bytesutil.ToBytes32(b.ParentRoot)
@@ -78,6 +66,11 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
if !s.stateGen.StateSummaryExists(ctx, parentRoot) && !s.beaconDB.HasBlock(ctx, parentRoot) {
return errors.New("could not reconstruct parent state")
}
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot)); err != nil {
return err
}
has, err := s.stateGen.HasState(ctx, parentRoot)
if err != nil {
return err
@@ -94,7 +87,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
// VerifyBlkDescendant validates input block root is a descendant of the
// current finalized block root.
func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error {
ctx, span := trace.StartSpan(ctx, "forkChoice.VerifyBlkDescendant")
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)
@@ -126,7 +119,10 @@ 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 {
finalizedSlot := helpers.StartSlot(s.finalizedCheckpt.Epoch)
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)
}
@@ -157,7 +153,11 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
}
newJustifiedBlock := newJustifiedBlockSigned.Block
if newJustifiedBlock.Slot <= helpers.StartSlot(s.justifiedCheckpt.Epoch) {
jSlot, err := helpers.StartSlot(s.justifiedCheckpt.Epoch)
if err != nil {
return false, err
}
if newJustifiedBlock.Slot <= jSlot {
return false, nil
}
var justifiedBlockSigned *ethpb.SignedBeaconBlock
@@ -227,6 +227,10 @@ func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) err
}
s.clearInitSyncBlocks()
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
return err
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
@@ -235,9 +239,7 @@ func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) err
return errors.Wrap(err, "could not migrate to cold")
}
s.attPool.ClearSeenAtts()
return s.beaconDB.SaveFinalizedCheckpoint(ctx, cp)
return nil
}
// ancestor returns the block root of an ancestry block from the input block root.
@@ -253,7 +255,39 @@ func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) err
// # 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) {
ctx, span := trace.StartSpan(ctx, "forkChoice.ancestor")
ctx, span := trace.StartSpan(ctx, "blockChain.ancestor")
defer span.End()
r := bytesutil.ToBytes32(root)
// Get ancestor root from fork choice store instead of recursively looking up blocks in DB.
// This is most optimal outcome.
ar, err := s.ancestorByForkChoiceStore(ctx, r, slot)
if err != nil {
// Try getting ancestor root from DB when failed to retrieve from fork choice store.
// This is the second line of defense for retrieving ancestor root.
ar, err = s.ancestorByDB(ctx, r, slot)
if err != nil {
return nil, err
}
}
return ar, nil
}
// 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) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByForkChoiceStore")
defer span.End()
if !s.forkChoiceStore.HasParent(r) {
return nil, errors.New("could not find root in fork choice store")
}
return s.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) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByDB")
defer span.End()
// Stop recursive ancestry lookup if context is cancelled.
@@ -261,13 +295,6 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
return nil, ctx.Err()
}
r := bytesutil.ToBytes32(root)
// Get ancestor root from fork choice store instead of recursively looking up blocks in DB.
// This is most optimal outcome.
if s.forkChoiceStore.HasParent(r) {
return s.forkChoiceStore.AncestorRoot(ctx, r, slot)
}
signed, err := s.beaconDB.Block(ctx, r)
if err != nil {
return nil, errors.Wrap(err, "could not get ancestor block")
@@ -282,10 +309,10 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
}
b := signed.Block
if b.Slot == slot || b.Slot < slot {
return root, nil
return r[:], nil
}
return s.ancestor(ctx, 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
@@ -308,14 +335,14 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *state
if !attestationutil.CheckPointIsEqual(s.justifiedCheckpt, state.CurrentJustifiedCheckpoint()) {
if state.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
s.justifiedCheckpt = state.CurrentJustifiedCheckpoint()
if err := s.cacheJustifiedStateBalances(ctx, bytesutil.ToBytes32(s.justifiedCheckpt.Root)); err != nil {
return err
}
return nil
return s.cacheJustifiedStateBalances(ctx, bytesutil.ToBytes32(s.justifiedCheckpt.Root))
}
// Update justified if store justified is not in chain with finalized check point.
finalizedSlot := helpers.StartSlot(s.finalizedCheckpt.Epoch)
finalizedSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
return err
}
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))
anc, err := s.ancestor(ctx, justifiedRoot[:], finalizedSlot)
if err != nil {
@@ -334,13 +361,17 @@ 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,
fCheckpoint *ethpb.Checkpoint, jCheckpoint *ethpb.Checkpoint) error {
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
pendingNodes := make([]*ethpb.BeaconBlock, 0)
parentRoot := bytesutil.ToBytes32(blk.ParentRoot)
slot := blk.Slot
// Fork choice only matters from last finalized slot.
higherThanFinalized := slot > helpers.StartSlot(s.finalizedCheckpt.Epoch)
fSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
return err
}
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)
@@ -351,14 +382,14 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
pendingNodes = append(pendingNodes, b.Block)
parentRoot = bytesutil.ToBytes32(b.Block.ParentRoot)
slot = b.Block.Slot
higherThanFinalized = slot > helpers.StartSlot(s.finalizedCheckpt.Epoch)
higherThanFinalized = slot > fSlot
}
// Insert parent nodes to fork choice store in reverse order.
// Lower slots should be at the end of the list.
for i := len(pendingNodes) - 1; i >= 0; i-- {
b := pendingNodes[i]
r, err := stateutil.BlockRoot(b)
r, err := b.HashTreeRoot()
if err != nil {
return err
}

View File

@@ -2,12 +2,11 @@ package blockchain
import (
"context"
"strings"
"testing"
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
@@ -16,16 +15,14 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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/roughtime"
"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_OnBlock(t *testing.T) {
@@ -42,50 +39,66 @@ func TestStore_OnBlock(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
validGenesisRoot, err := stateutil.BlockRoot(genesis.Block)
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[:])
require.NoError(t, err)
random := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 1, ParentRoot: validGenesisRoot[:]}}
random := testutil.NewBeaconBlock()
random.Block.Slot = 1
random.Block.ParentRoot = validGenesisRoot[:]
assert.NoError(t, db.SaveBlock(ctx, random))
randomParentRoot, err := stateutil.BlockRoot(random.Block)
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))
randomParentRoot2 := roots[1]
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2[:]}))
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)))
tests := []struct {
name string
blk *ethpb.BeaconBlock
blk *ethpb.SignedBeaconBlock
s *stateTrie.BeaconState
time uint64
wantErrString string
}{
{
name: "parent block root does not have a state",
blk: &ethpb.BeaconBlock{},
blk: testutil.NewBeaconBlock(),
s: st.Copy(),
wantErrString: "could not reconstruct parent state",
},
{
name: "block is from the future",
blk: &ethpb.BeaconBlock{ParentRoot: randomParentRoot[:], Slot: params.BeaconConfig().FarFutureEpoch},
name: "block is from the future",
blk: func() *ethpb.SignedBeaconBlock {
b := testutil.NewBeaconBlock()
b.Block.ParentRoot = randomParentRoot2
b.Block.Slot = params.BeaconConfig().FarFutureEpoch
return b
}(),
s: st.Copy(),
wantErrString: "far distant future",
wantErrString: "is in the far distant future",
},
{
name: "could not get finalized block",
blk: &ethpb.BeaconBlock{ParentRoot: randomParentRoot[:]},
name: "could not get finalized block",
blk: func() *ethpb.SignedBeaconBlock {
b := testutil.NewBeaconBlock()
b.Block.ParentRoot = randomParentRoot[:]
return b
}(),
s: st.Copy(),
wantErrString: "is not a descendent of the current finalized block",
},
{
name: "same slot as finalized block",
blk: &ethpb.BeaconBlock{Slot: 0, ParentRoot: randomParentRoot2},
name: "same slot as finalized block",
blk: func() *ethpb.SignedBeaconBlock {
b := testutil.NewBeaconBlock()
b.Block.Slot = 0
b.Block.ParentRoot = randomParentRoot2
return b
}(),
s: st.Copy(),
wantErrString: "block is equal or earlier than finalized block, slot 0 < slot 0",
},
@@ -99,9 +112,9 @@ func TestStore_OnBlock(t *testing.T) {
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: validGenesisRoot[:]}
service.finalizedCheckpt.Root = roots[0]
root, err := stateutil.BlockRoot(tt.blk)
root, err := tt.blk.Block.HashTreeRoot()
assert.NoError(t, err)
err = service.onBlock(ctx, &ethpb.SignedBeaconBlock{Block: tt.blk}, root)
err = service.onBlock(ctx, tt.blk, root)
assert.ErrorContains(t, tt.wantErrString, err)
})
}
@@ -121,13 +134,20 @@ func TestStore_OnBlockBatch(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, 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)
st, keys := testutil.DeterministicGenesisState(t, 64)
bState := st.Copy()
blks := []*ethpb.SignedBeaconBlock{}
blkRoots := [][32]byte{}
var blks []*ethpb.SignedBeaconBlock
var blkRoots [][32]byte
var firstState *stateTrie.BeaconState
for i := 1; i < 10; i++ {
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), uint64(i))
@@ -137,11 +157,14 @@ func TestStore_OnBlockBatch(t *testing.T) {
if i == 1 {
firstState = bState.Copy()
}
root, err := stateutil.BlockRoot(b.Block)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
service.saveInitSyncBlock(root, b)
blks = append(blks, 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))
_, _, err = service.onBlockBatch(ctx, blks[1:], blkRoots[1:])
@@ -159,17 +182,17 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
require.NoError(t, err)
service.genesisTime = time.Now()
update, err := service.shouldUpdateCurrentJustified(ctx, &ethpb.Checkpoint{})
update, err := service.shouldUpdateCurrentJustified(ctx, &ethpb.Checkpoint{Root: make([]byte, 32)})
require.NoError(t, err)
assert.Equal(t, true, update, "Should be able to update justified")
lastJustifiedBlk := testutil.NewBeaconBlock()
lastJustifiedBlk.Block.ParentRoot = bytesutil.PadTo([]byte{'G'}, 32)
lastJustifiedRoot, err := stateutil.BlockRoot(lastJustifiedBlk.Block)
lastJustifiedRoot, err := lastJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
newJustifiedBlk := testutil.NewBeaconBlock()
newJustifiedBlk.Block.Slot = 1
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := stateutil.BlockRoot(newJustifiedBlk.Block)
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))
@@ -193,11 +216,11 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
require.NoError(t, err)
lastJustifiedBlk := testutil.NewBeaconBlock()
lastJustifiedBlk.Block.ParentRoot = bytesutil.PadTo([]byte{'G'}, 32)
lastJustifiedRoot, err := stateutil.BlockRoot(lastJustifiedBlk.Block)
lastJustifiedRoot, err := lastJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
newJustifiedBlk := testutil.NewBeaconBlock()
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := stateutil.BlockRoot(newJustifiedBlk.Block)
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))
@@ -212,9 +235,6 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
}
func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{NewStateMgmt: true})
defer resetCfg()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
@@ -227,17 +247,27 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
r := [32]byte{'A'}
b := &ethpb.BeaconBlock{Slot: 1, ParentRoot: r[:]}
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: r[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, r, s))
require.NoError(t, service.verifyBlkPreState(ctx, b))
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, 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)
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))
}
func TestCachedPreState_CanGetFromDB(t *testing.T) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{NewStateMgmt: true})
defer resetCfg()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
@@ -248,19 +278,30 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
r := [32]byte{'A'}
b := &ethpb.BeaconBlock{Slot: 1, ParentRoot: r[:]}
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, 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.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
err = service.verifyBlkPreState(ctx, b)
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
err = service.verifyBlkPreState(ctx, 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})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: r[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, r, s))
require.NoError(t, service.verifyBlkPreState(ctx, b))
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))
}
func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
@@ -271,14 +312,13 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
signedBlock := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
signedBlock := testutil.NewBeaconBlock()
require.NoError(t, db.SaveBlock(ctx, signedBlock))
r, err := stateutil.BlockRoot(signedBlock.Block)
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()
service.initSyncState[r] = st.Copy()
require.NoError(t, db.SaveState(ctx, st.Copy(), r))
// Could update
@@ -303,12 +343,12 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
require.NoError(t, db.SaveBlock(ctx, genesis))
validGenesisRoot, err := stateutil.BlockRoot(genesis.Block)
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st := testutil.NewBeaconState()
@@ -317,10 +357,12 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
require.NoError(t, err)
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
block := &ethpb.BeaconBlock{Slot: 9, ParentRoot: roots[8], Body: &ethpb.BeaconBlockBody{Graffiti: []byte{}}}
block := testutil.NewBeaconBlock()
block.Block.Slot = 9
block.Block.ParentRoot = roots[8]
err = service.fillInForkChoiceMissingBlocks(
context.Background(), block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
@@ -344,22 +386,27 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, db.SaveBlock(ctx, genesis))
validGenesisRoot, err := stateutil.BlockRoot(genesis.Block)
validGenesisRoot, err := genesis.Block.HashTreeRoot()
assert.NoError(t, err)
st := testutil.NewBeaconState()
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
// Define a tree branch, slot 63 <- 64 <- 65
b63 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 63, Body: &ethpb.BeaconBlockBody{}}}
b63 := testutil.NewBeaconBlock()
b63.Block.Slot = 63
require.NoError(t, service.beaconDB.SaveBlock(ctx, b63))
r63, err := stateutil.BlockRoot(b63.Block)
r63, err := b63.Block.HashTreeRoot()
require.NoError(t, err)
b64 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 64, ParentRoot: r63[:], Body: &ethpb.BeaconBlockBody{}}}
b64 := testutil.NewBeaconBlock()
b64.Block.Slot = 64
b64.Block.ParentRoot = r63[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b64))
r64, err := stateutil.BlockRoot(b64.Block)
r64, err := b64.Block.HashTreeRoot()
require.NoError(t, err)
b65 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 65, ParentRoot: r64[:], Body: &ethpb.BeaconBlockBody{}}}
b65 := testutil.NewBeaconBlock()
b65.Block.Slot = 65
b65.Block.ParentRoot = r64[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b65))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
@@ -380,58 +427,74 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
// \- B3 - B4 - B6 - B8
// (B1, and B3 are all from the same slots)
func blockTree1(db db.Database, genesisRoot []byte) ([][]byte, error) {
b0 := &ethpb.BeaconBlock{Slot: 0, ParentRoot: genesisRoot}
r0, err := ssz.HashTreeRoot(b0)
genesisRoot = bytesutil.PadTo(genesisRoot, 32)
b0 := testutil.NewBeaconBlock()
b0.Block.Slot = 0
b0.Block.ParentRoot = genesisRoot
r0, err := b0.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b1 := &ethpb.BeaconBlock{Slot: 1, ParentRoot: r0[:]}
r1, err := ssz.HashTreeRoot(b1)
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.ParentRoot = r0[:]
r1, err := b1.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b3 := &ethpb.BeaconBlock{Slot: 3, ParentRoot: r0[:]}
r3, err := ssz.HashTreeRoot(b3)
b3 := testutil.NewBeaconBlock()
b3.Block.Slot = 3
b3.Block.ParentRoot = r0[:]
r3, err := b3.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b4 := &ethpb.BeaconBlock{Slot: 4, ParentRoot: r3[:]}
r4, err := ssz.HashTreeRoot(b4)
b4 := testutil.NewBeaconBlock()
b4.Block.Slot = 4
b4.Block.ParentRoot = r3[:]
r4, err := b4.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b5 := &ethpb.BeaconBlock{Slot: 5, ParentRoot: r4[:]}
r5, err := ssz.HashTreeRoot(b5)
b5 := testutil.NewBeaconBlock()
b5.Block.Slot = 5
b5.Block.ParentRoot = r4[:]
r5, err := b5.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b6 := &ethpb.BeaconBlock{Slot: 6, ParentRoot: r4[:]}
r6, err := ssz.HashTreeRoot(b6)
b6 := testutil.NewBeaconBlock()
b6.Block.Slot = 6
b6.Block.ParentRoot = r4[:]
r6, err := b6.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b7 := &ethpb.BeaconBlock{Slot: 7, ParentRoot: r5[:]}
r7, err := ssz.HashTreeRoot(b7)
b7 := testutil.NewBeaconBlock()
b7.Block.Slot = 7
b7.Block.ParentRoot = r5[:]
r7, err := b7.Block.HashTreeRoot()
if err != nil {
return nil, err
}
b8 := &ethpb.BeaconBlock{Slot: 8, ParentRoot: r6[:]}
r8, err := ssz.HashTreeRoot(b8)
b8 := testutil.NewBeaconBlock()
b8.Block.Slot = 8
b8.Block.ParentRoot = r6[:]
r8, err := b8.Block.HashTreeRoot()
if err != nil {
return nil, err
}
st := testutil.NewBeaconState()
for _, b := range []*ethpb.BeaconBlock{b0, b1, b3, b4, b5, b6, b7, b8} {
for _, b := range []*ethpb.SignedBeaconBlock{b0, b1, b3, b4, b5, b6, b7, b8} {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.ParentRoot, 32)
beaconBlock.Block.Body = &ethpb.BeaconBlockBody{}
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
if err := db.SaveBlock(context.Background(), beaconBlock); err != nil {
return nil, err
}
if err := db.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
return nil, err
return nil, errors.Wrap(err, "could not save state")
}
}
if err := db.SaveState(context.Background(), st.Copy(), r1); err != nil {
@@ -447,11 +510,20 @@ func blockTree1(db db.Database, genesisRoot []byte) ([][]byte, error) {
}
func TestCurrentSlot_HandlesOverflow(t *testing.T) {
svc := Service{genesisTime: roughtime.Now().Add(1 * time.Hour)}
svc := Service{genesisTime: timeutils.Now().Add(1 * time.Hour)}
slot := svc.CurrentSlot()
require.Equal(t, uint64(0), slot, "Unexpected slot")
}
func TestAncestorByDB_CtxErr(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
service, err := NewService(ctx, &Config{})
require.NoError(t, err)
cancel()
_, err = service.ancestorByDB(ctx, [32]byte{}, 0)
require.ErrorContains(t, "context canceled", err)
}
func TestAncestor_HandleSkipSlot(t *testing.T) {
ctx := context.Background()
@@ -461,20 +533,25 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b1 := &ethpb.BeaconBlock{Slot: 1, ParentRoot: []byte{'a'}}
r1, err := ssz.HashTreeRoot(b1)
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
b100 := &ethpb.BeaconBlock{Slot: 100, ParentRoot: r1[:]}
r100, err := ssz.HashTreeRoot(b100)
b100 := testutil.NewBeaconBlock()
b100.Block.Slot = 100
b100.Block.ParentRoot = r1[:]
r100, err := b100.Block.HashTreeRoot()
require.NoError(t, err)
b200 := &ethpb.BeaconBlock{Slot: 200, ParentRoot: r100[:]}
r200, err := ssz.HashTreeRoot(b200)
b200 := testutil.NewBeaconBlock()
b200.Block.Slot = 200
b200.Block.ParentRoot = r100[:]
r200, err := b200.Block.HashTreeRoot()
require.NoError(t, err)
for _, b := range []*ethpb.BeaconBlock{b1, b100, b200} {
for _, b := range []*ethpb.SignedBeaconBlock{b1, b100, b200} {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.ParentRoot, 32)
beaconBlock.Block.Body = &ethpb.BeaconBlockBody{}
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, db.SaveBlock(context.Background(), beaconBlock))
}
@@ -493,6 +570,82 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
}
}
func TestAncestor_CanUseForkchoice(t *testing.T) {
ctx := context.Background()
cfg := &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
b100 := testutil.NewBeaconBlock()
b100.Block.Slot = 100
b100.Block.ParentRoot = r1[:]
r100, err := b100.Block.HashTreeRoot()
require.NoError(t, err)
b200 := testutil.NewBeaconBlock()
b200.Block.Slot = 200
b200.Block.ParentRoot = r100[:]
r200, err := b200.Block.HashTreeRoot()
require.NoError(t, err)
for _, b := range []*ethpb.SignedBeaconBlock{b1, b100, b200} {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
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.
}
r, err := service.ancestor(context.Background(), r200[:], 150)
require.NoError(t, err)
if bytesutil.ToBytes32(r) != r100 {
t.Error("Did not get correct root")
}
}
func TestAncestor_CanUseDB(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)
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
b100 := testutil.NewBeaconBlock()
b100.Block.Slot = 100
b100.Block.ParentRoot = r1[:]
r100, err := b100.Block.HashTreeRoot()
require.NoError(t, err)
b200 := testutil.NewBeaconBlock()
b200.Block.Slot = 200
b200.Block.ParentRoot = r100[:]
r200, err := b200.Block.HashTreeRoot()
require.NoError(t, err)
for _, b := range []*ethpb.SignedBeaconBlock{b1, b100, b200} {
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, service.forkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
r, err := service.ancestor(context.Background(), r200[:], 150)
require.NoError(t, err)
if bytesutil.ToBytes32(r) != r100 {
t.Error("Did not get correct root")
}
}
func TestEnsureRootNotZeroHashes(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
@@ -557,16 +710,20 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
require.NoError(t, service.beaconDB.SaveState(ctx, genesisState, bytesutil.ToBytes32(test.want.Root)))
if test.args.diffFinalizedCheckPoint {
b1 := &ethpb.BeaconBlock{Slot: 1, ParentRoot: []byte{'a'}}
r1, err := ssz.HashTreeRoot(b1)
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
b100 := &ethpb.BeaconBlock{Slot: 100, ParentRoot: r1[:]}
r100, err := ssz.HashTreeRoot(b100)
b100 := testutil.NewBeaconBlock()
b100.Block.Slot = 100
b100.Block.ParentRoot = r1[:]
r100, err := b100.Block.HashTreeRoot()
require.NoError(t, err)
for _, b := range []*ethpb.BeaconBlock{b1, b100} {
for _, b := range []*ethpb.SignedBeaconBlock{b1, b100} {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.ParentRoot, 32)
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), beaconBlock))
}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: []byte{'c'}, Epoch: 1}
@@ -584,14 +741,14 @@ func TestVerifyBlkDescendant(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
r, err := stateutil.BlockRoot(b.Block)
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, b))
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.Body.Graffiti = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := stateutil.BlockRoot(b1.Block)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, b1))
@@ -601,18 +758,16 @@ func TestVerifyBlkDescendant(t *testing.T) {
finalizedSlot uint64
}
tests := []struct {
name string
args args
shouldError bool
err string
name string
args args
wantedErr string
}{
{
name: "could not get finalized block in block service cache",
args: args{
finalizedRoot: [32]byte{'a'},
},
shouldError: true,
err: "nil finalized block",
wantedErr: "nil finalized block",
},
{
name: "could not get finalized block root in DB",
@@ -620,8 +775,7 @@ func TestVerifyBlkDescendant(t *testing.T) {
finalizedRoot: r,
parentRoot: [32]byte{'a'},
},
shouldError: true,
err: "could not get finalized block root",
wantedErr: "could not get finalized block root",
},
{
name: "is not descendant",
@@ -629,8 +783,7 @@ func TestVerifyBlkDescendant(t *testing.T) {
finalizedRoot: r1,
parentRoot: r,
},
shouldError: true,
err: "is not a descendent of the current finalized block slot",
wantedErr: "is not a descendent of the current finalized block slot",
},
{
name: "is descendant",
@@ -638,22 +791,19 @@ func TestVerifyBlkDescendant(t *testing.T) {
finalizedRoot: r,
parentRoot: r,
},
shouldError: false,
},
}
for _, test := range tests {
for _, tt := range tests {
service, err := NewService(ctx, &Config{BeaconDB: db, StateGen: stategen.New(db, sc), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: test.args.finalizedRoot[:],
Root: tt.args.finalizedRoot[:],
}
err = service.VerifyBlkDescendant(ctx, test.args.parentRoot)
if test.shouldError {
if err == nil || !strings.Contains(err.Error(), test.err) {
t.Error("Did not get wanted error")
}
err = service.VerifyBlkDescendant(ctx, tt.args.parentRoot)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else if err != nil {
t.Error(err)
assert.NoError(t, err)
}
}
}
@@ -665,8 +815,8 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gBlk := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
gRoot, err := stateutil.BlockRoot(gBlk.Block)
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))
@@ -683,8 +833,18 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
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)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
assert.DeepEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
}
func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s := testutil.NewBeaconState()
require.NoError(t, s.SetSlot(1))
service.head = &head{}
require.ErrorContains(t, "failed to initialize precompute: nil inner state", service.handleEpochBoundary(ctx, s))
}

View File

@@ -1,19 +1,17 @@
package blockchain
import (
"bytes"
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@@ -22,8 +20,9 @@ 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
IsValidAttestation(ctx context.Context, att *ethpb.Attestation) bool
AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error)
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
VerifyFinalizedConsistency(ctx context.Context, root []byte) error
}
// ReceiveAttestationNoPubsub is a function that defines the operations that are performed on
@@ -40,40 +39,57 @@ func (s *Service) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Att
return errors.Wrap(err, "could not process attestation")
}
if !featureconfig.Get().DisableUpdateHeadPerAttestation {
// This updates fork choice head, if a new head could not be updated due to
// long range or intermediate forking. It simply logs a warning and returns nil
// as that's more appropriate than returning errors.
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
return nil
}
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
return nil
}
return nil
}
// IsValidAttestation returns true if the attestation can be verified against its pre-state.
func (s *Service) IsValidAttestation(ctx context.Context, att *ethpb.Attestation) bool {
baseState, err := s.AttestationPreState(ctx, att)
if err != nil {
log.WithError(err).Error("Failed to get attestation pre state")
return false
}
if err := blocks.VerifyAttestation(ctx, baseState, att); err != nil {
log.WithError(err).Error("Failed to validate attestation")
return false
}
return true
}
// AttestationPreState returns the pre state of attestation.
func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error) {
ss, err := helpers.StartSlot(att.Data.Target.Epoch)
if err != nil {
return nil, err
}
if err := helpers.ValidateSlotClock(ss, uint64(s.genesisTime.Unix())); err != nil {
return nil, err
}
return s.getAttPreState(ctx, att.Data.Target)
}
// 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)
}
// VerifyFinalizedConsistency verifies input root is consistent with finalized store.
// When the input root is not be consistent with finalized store then we know it is not
// on the finalized check point that leads to current canonical chain and should be rejected accordingly.
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)) {
return nil
}
f := s.FinalizedCheckpt()
ss, err := helpers.StartSlot(f.Epoch)
if err != nil {
return err
}
r, err := s.ancestor(ctx, root, ss)
if err != nil {
return err
}
if !bytes.Equal(f.Root, r) {
return errors.New("Root and finalized store are not consistent")
}
return nil
}
// This processes attestations from the attestation pool to account for validator votes and fork choice.
func (s *Service) processAttestation(subscribedToStateEvents chan struct{}) {
// Wait for state to be initialized.
@@ -89,7 +105,7 @@ func (s *Service) processAttestation(subscribedToStateEvents chan struct{}) {
case <-s.ctx.Done():
return
case <-st.C():
ctx := context.Background()
ctx := s.ctx
atts := s.attPool.ForkchoiceAttestations()
for _, a := range atts {
// Based on the spec, don't process the attestation until the subsequent slot.
@@ -110,7 +126,7 @@ func (s *Service) processAttestation(subscribedToStateEvents chan struct{}) {
log.WithError(err).Error("Could not delete fork choice attestation in pool")
}
if !s.verifyCheckpointEpoch(a.Data.Target) {
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime) {
continue
}
@@ -127,23 +143,3 @@ func (s *Service) processAttestation(subscribedToStateEvents chan struct{}) {
}
}
}
// This verifies the epoch of input checkpoint is within current epoch and previous epoch
// with respect to current time. Returns true if it's within, false if it's not.
func (s *Service) verifyCheckpointEpoch(c *ethpb.Checkpoint) bool {
now := uint64(roughtime.Now().Unix())
genesisTime := uint64(s.genesisTime.Unix())
currentSlot := (now - genesisTime) / params.BeaconConfig().SecondsPerSlot
currentEpoch := helpers.SlotToEpoch(currentSlot)
var prevEpoch uint64
if currentEpoch > 1 {
prevEpoch = currentEpoch - 1
}
if c.Epoch != prevEpoch && c.Epoch != currentEpoch {
return false
}
return true
}

View File

@@ -1,22 +1,25 @@
package blockchain
import (
"context"
"testing"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestVerifyCheckpointEpoch_Ok(t *testing.T) {
func TestAttestationCheckPtState_FarFutureSlot(t *testing.T) {
helpers.ClearCache()
db, sc := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService.genesisTime = time.Now()
assert.Equal(t, true, chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{}))
assert.Equal(t, false, chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{Epoch: 1}))
e := helpers.MaxSlotBuffer/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)
}

View File

@@ -7,12 +7,16 @@ import (
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"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"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
// 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
@@ -58,8 +62,13 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
return err
}
// Have we been finalizing? Should we start saving hot states to db?
if err := s.checkSaveHotStateDB(ctx); err != nil {
return err
}
// 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)
@@ -95,7 +104,7 @@ func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.Sign
})
// 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)
// Log state transition data.
log.WithFields(logrus.Fields{
@@ -139,7 +148,14 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
})
// 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 {
// log.Fatalf will prevent defer from being called
span.End()
// Exit run time if the node failed to verify weak subjectivity checkpoint.
log.Fatalf("Could not verify weak subjectivity checkpoint: %v", err)
}
return nil
@@ -172,3 +188,21 @@ func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
}
return nil
}
// This checks whether it's time to start saving hot state to DB.
// It's time when there's `epochsSinceFinalitySaveHotStateDB` epochs of non-finality.
func (s *Service) checkSaveHotStateDB(ctx context.Context) error {
currentEpoch := helpers.SlotToEpoch(s.CurrentSlot())
// Prevent `sinceFinality` going underflow.
var sinceFinality uint64
if currentEpoch > s.finalizedCheckpt.Epoch {
sinceFinality = currentEpoch - s.finalizedCheckpt.Epoch
}
if sinceFinality >= uint64(epochsSinceFinalitySaveHotStateDB) {
s.stateGen.EnableSaveHotStateToDB(ctx)
return nil
}
return s.stateGen.DisableSaveHotStateToDB(ctx)
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"sync"
"testing"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
@@ -12,12 +13,12 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"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"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestService_ReceiveBlock(t *testing.T) {
@@ -37,10 +38,10 @@ func TestService_ReceiveBlock(t *testing.T) {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantErr bool
check func(*testing.T, *Service)
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
@@ -139,13 +140,16 @@ func TestService_ReceiveBlock(t *testing.T) {
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := stateutil.BlockRoot(gBlk.Block)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := stateutil.BlockRoot(tt.args.block.Block)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
if err := s.ReceiveBlock(ctx, tt.args.block, root); (err != nil) != tt.wantErr {
t.Errorf("ReceiveBlock() error = %v, wantErr %v", err, tt.wantErr)
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)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
@@ -177,9 +181,10 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := stateutil.BlockRoot(gBlk.Block)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := stateutil.BlockRoot(b.Block)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
wg := sync.WaitGroup{}
wg.Add(1)
@@ -201,9 +206,7 @@ func TestService_ReceiveBlockInitialSync(t *testing.T) {
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)
if err != nil {
t.Error(err)
}
assert.NoError(t, err)
return blk
}
@@ -211,10 +214,10 @@ func TestService_ReceiveBlockInitialSync(t *testing.T) {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantErr bool
check func(*testing.T, *Service)
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
@@ -261,14 +264,17 @@ func TestService_ReceiveBlockInitialSync(t *testing.T) {
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := stateutil.BlockRoot(gBlk.Block)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := stateutil.BlockRoot(tt.args.block.Block)
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
if err := s.ReceiveBlockInitialSync(ctx, tt.args.block, root); (err != nil) != tt.wantErr {
t.Errorf("ReceiveBlockInitialSync() error = %v, wantErr %v", err, tt.wantErr)
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)
}
})
@@ -281,9 +287,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
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)
if err != nil {
t.Error(err)
}
assert.NoError(t, err)
return blk
}
@@ -291,10 +295,10 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantErr bool
check func(*testing.T, *Service)
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
@@ -322,8 +326,8 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
genesisBlockRoot, err := genesis.HashTreeRoot(ctx)
require.NoError(t, err)
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
@@ -341,15 +345,18 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := stateutil.BlockRoot(gBlk.Block)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := stateutil.BlockRoot(tt.args.block.Block)
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
blks := []*ethpb.SignedBeaconBlock{tt.args.block}
roots := [][32]byte{root}
if err := s.ReceiveBlockBatch(ctx, blks, roots); (err != nil) != tt.wantErr {
t.Errorf("ReceiveBlockBatch() error = %v, wantErr %v", err, tt.wantErr)
err = s.ReceiveBlockBatch(ctx, blks, roots)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
@@ -357,7 +364,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
}
func TestService_HasInitSyncBlock(t *testing.T) {
s, err := NewService(context.Background(), &Config{})
s, err := NewService(context.Background(), &Config{StateNotifier: &blockchainTesting.MockStateNotifier{}})
require.NoError(t, err)
r := [32]byte{'a'}
if s.HasInitSyncBlock(r) {
@@ -368,3 +375,41 @@ func TestService_HasInitSyncBlock(t *testing.T) {
t.Error("Should have block")
}
}
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
require.NoError(t, err)
st := params.BeaconConfig().SlotsPerEpoch * uint64(epochsSinceFinalitySaveHotStateDB)
s.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
s.finalizedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
assert.LogsContain(t, hook, "Entering mode to save hot states in DB")
}
func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
s.genesisTime = time.Now()
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
assert.LogsContain(t, hook, "Exiting mode to save hot states in DB")
}
func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(db, stateSummaryCache)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 10000000}
s.genesisTime = time.Now()
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
assert.LogsDoNotContain(t, hook, "Entering mode to save hot states in DB")
}

View File

@@ -30,51 +30,50 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
)
// Service represents a service that handles the internal
// logic of managing the full PoS beacon chain.
type Service struct {
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
initSyncState map[[32]byte]*stateTrie.BeaconState
boundaryRoots [][32]byte
checkpointState *cache.CheckpointStateCache
checkpointStateLock sync.Mutex
stateGen *stategen.State
opsService *attestations.Service
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
initSyncBlocksLock sync.RWMutex
recentCanonicalBlocks map[[32]byte]bool
recentCanonicalBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
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
boundaryRoots [][32]byte
checkpointStateCache *cache.CheckpointStateCache
stateGen *stategen.State
opsService *attestations.Service
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
initSyncBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
wsEpoch uint64
wsRoot []byte
wsVerified bool
}
// Config options for the service.
@@ -92,6 +91,8 @@ type Config struct {
ForkChoiceStore f.ForkChoicer
OpsService *attestations.Service
StateGen *stategen.State
WspBlockRoot []byte
WspEpoch uint64
}
// NewService instantiates a new block service instance that will
@@ -99,36 +100,31 @@ type Config struct {
func NewService(ctx context.Context, cfg *Config) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
return &Service{
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,
initSyncState: make(map[[32]byte]*stateTrie.BeaconState),
boundaryRoots: [][32]byte{},
checkpointState: cache.NewCheckpointStateCache(),
opsService: cfg.OpsService,
stateGen: cfg.StateGen,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
recentCanonicalBlocks: make(map[[32]byte]bool),
justifiedBalances: make([]uint64, 0),
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),
justifiedBalances: make([]uint64, 0),
wsEpoch: cfg.WspEpoch,
wsRoot: cfg.WspBlockRoot,
}, nil
}
// Start a blockchain service's main event loop.
func (s *Service) Start() {
beaconState, err := s.beaconDB.HeadState(s.ctx)
if err != nil {
log.Fatalf("Could not fetch beacon state: %v", err)
}
// 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.
@@ -137,11 +133,25 @@ func (s *Service) Start() {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if beaconState == nil {
beaconState, err = s.stateGen.StateByRoot(s.ctx, bytesutil.ToBytes32(cp.Root))
r := bytesutil.ToBytes32(cp.Root)
// Before the first finalized epoch, in the current epoch,
// the finalized root is defined as zero hashes instead of genesis root hash.
// We want to use genesis root to retrieve for state.
if r == params.BeaconConfig().ZeroHash {
genesisBlock, err := s.beaconDB.GenesisBlock(s.ctx)
if err != nil {
log.Fatalf("Could not fetch beacon state by root: %v", err)
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if genesisBlock != nil {
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)
if err != nil {
log.Fatalf("Could not fetch beacon state by root: %v", err)
}
// Make sure that attestation processor is subscribed and ready for state initializing event.
@@ -150,8 +160,8 @@ func (s *Service) Start() {
// If the chain has already been initialized, simply start the block processing routine.
if beaconState != nil {
log.Info("Blockchain data already exists in DB, initializing...")
s.genesisTime = time.Unix(int64(helpers.GenesisTime(beaconState)), 0)
s.opsService.SetGenesisTime(helpers.GenesisTime(beaconState))
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
s.opsService.SetGenesisTime(beaconState.GenesisTime())
if err := s.initializeChainInfo(s.ctx); err != nil {
log.Fatalf("Could not set up chain info: %v", err)
}
@@ -183,6 +193,24 @@ func (s *Service) Start() {
s.prevFinalizedCheckpt = stateTrie.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)
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
// Exit run time if the node failed to verify weak subjectivity checkpoint.
log.Fatalf("Could not verify weak subjectivity checkpoint: %v", err)
}
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Initialized,
Data: &statefeed.InitializedData{
@@ -258,7 +286,7 @@ func (s *Service) initializeBeaconChain(
genesisTime time.Time,
preGenesisState *stateTrie.BeaconState,
eth1data *ethpb.Eth1Data) (*stateTrie.BeaconState, error) {
_, span := trace.StartSpan(context.Background(), "beacon-chain.Service.initializeBeaconChain")
ctx, span := trace.StartSpan(ctx, "beacon-chain.Service.initializeBeaconChain")
defer span.End()
s.genesisTime = genesisTime
unixTime := uint64(genesisTime.Unix())
@@ -285,7 +313,7 @@ func (s *Service) initializeBeaconChain(
return nil, err
}
s.opsService.SetGenesisTime(helpers.GenesisTime(genesisState))
s.opsService.SetGenesisTime(genesisState.GenesisTime())
return genesisState, nil
}
@@ -295,9 +323,13 @@ func (s *Service) Stop() error {
defer s.cancel()
if s.stateGen != nil && s.head != nil && s.head.state != nil {
return s.stateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root)
if err := s.stateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
return err
}
}
return nil
// Save initial sync cached blocks to the DB before stop.
return s.beaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks())
}
// Status always returns nil unless there is an error condition that causes
@@ -309,12 +341,6 @@ func (s *Service) Status() error {
return nil
}
// ClearCachedStates removes all stored caches states. This is done after the node
// is synced.
func (s *Service) ClearCachedStates() {
s.initSyncState = map[[32]byte]*stateTrie.BeaconState{}
}
// 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)
@@ -322,7 +348,7 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.B
return err
}
genesisBlk := blocks.NewGenesisBlock(stateRoot[:])
genesisBlkRoot, err := stateutil.BlockRoot(genesisBlk.Block)
genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get genesis block root")
}
@@ -386,22 +412,28 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if genesisBlock == nil {
return errors.New("no genesis block in db")
}
genesisBlkRoot, err := stateutil.BlockRoot(genesisBlock.Block)
genesisBlkRoot, err := genesisBlock.Block.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get signing root of genesis block")
}
s.genesisRoot = genesisBlkRoot
if flags.Get().UnsafeSync {
if flags.Get().HeadSync {
headBlock, err := s.beaconDB.HeadBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not retrieve head block")
}
headRoot, err := stateutil.BlockRoot(headBlock.Block)
headRoot, err := headBlock.Block.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not hash head block")
}
headState, err := s.beaconDB.HeadState(ctx)
finalizedState, err := s.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)
if err != nil {
return errors.Wrap(err, "could not retrieve head state")
}
@@ -418,17 +450,13 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
// would be the genesis state and block.
return errors.New("no finalized epoch in the database")
}
finalizedRoot := bytesutil.ToBytes32(finalized.Root)
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
var finalizedState *stateTrie.BeaconState
finalizedState, err = s.stateGen.Resume(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
finalizedRoot = s.beaconDB.LastArchivedRoot(ctx)
if finalizedRoot == params.BeaconConfig().ZeroHash {
finalizedRoot = bytesutil.ToBytes32(finalized.Root)
}
finalizedBlock, err := s.beaconDB.Block(ctx, finalizedRoot)
if err != nil {
@@ -445,7 +473,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
// This is called when a client starts from non-genesis slot. This passes last justified and finalized
// information to fork choice service to initializes fork choice store.
func (s *Service) resumeForkChoice(justifiedCheckpoint *ethpb.Checkpoint, finalizedCheckpoint *ethpb.Checkpoint) {
func (s *Service) resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint *ethpb.Checkpoint) {
store := protoarray.New(justifiedCheckpoint.Epoch, finalizedCheckpoint.Epoch, bytesutil.ToBytes32(finalizedCheckpoint.Root))
s.forkChoiceStore = store
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
@@ -25,7 +24,6 @@ import (
"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/stateutil"
protodb "github.com/prysmaticlabs/prysm/proto/beacon/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -69,7 +67,7 @@ func (mb *mockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, _ *
return nil
}
var _ = p2p.Broadcaster(&mockBroadcaster{})
var _ p2p.Broadcaster = (*mockBroadcaster)(nil)
func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummaryCache) *Service {
endpoint := "http://127.0.0.1"
@@ -103,7 +101,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
opsService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
require.NoError(t, err)
depositCache, err := depositcache.NewDepositCache()
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
@@ -120,9 +118,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
}
// Safe a state in stategen to purposes of testing a service stop / shutdown.
if err := cfg.StateGen.SaveState(ctx, bytesutil.ToBytes32(bState.FinalizedCheckpoint().Root), bState); err != nil {
t.Fatal(err)
}
require.NoError(t, cfg.StateGen.SaveState(ctx, bytesutil.ToBytes32(bState.FinalizedCheckpoint().Root), bState))
chainService, err := NewService(ctx, cfg)
require.NoError(t, err, "Unable to setup chain service")
@@ -139,7 +135,7 @@ func TestChainStartStop_Initialized(t *testing.T) {
chainService := setupBeaconChain(t, db, sc)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := stateutil.BlockRoot(genesisBlk.Block)
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
@@ -148,6 +144,33 @@ func TestChainStartStop_Initialized(t *testing.T) {
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[:]}))
// Test the start function.
chainService.Start()
require.NoError(t, chainService.Stop(), "Unable to stop chain service")
// The context should have been canceled.
assert.Equal(t, context.Canceled, chainService.ctx.Err(), "Context was not canceled")
require.LogsContain(t, hook, "data already exists")
}
func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
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[:]}))
// Test the start function.
chainService.Start()
@@ -179,11 +202,13 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
err = genState.SetEth1Data(&ethpb.Eth1Data{
DepositRoot: hashTreeRoot[:],
DepositCount: uint64(len(deposits)),
BlockHash: make([]byte, 32),
})
require.NoError(t, err)
genState, err = b.ProcessPreGenesisDeposits(ctx, genState, deposits)
require.NoError(t, err)
_, err = bc.initializeBeaconChain(ctx, time.Unix(0, 0), genState, &ethpb.Eth1Data{DepositRoot: hashTreeRoot[:]})
_, err = bc.initializeBeaconChain(ctx, time.Unix(0, 0), genState, &ethpb.Eth1Data{DepositRoot: hashTreeRoot[:], BlockHash: make([]byte, 32)})
require.NoError(t, err)
_, err = bc.HeadState(ctx)
@@ -193,7 +218,9 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
if headBlk == nil {
t.Error("Head state can't be nil after initialize beacon chain")
}
if bc.headRoot() == params.BeaconConfig().ZeroHash {
r, err := bc.HeadRoot(ctx)
require.NoError(t, err)
if bytesutil.ToBytes32(r) == params.BeaconConfig().ZeroHash {
t.Error("Canonical root for slot 0 can't be zeros after initialize beacon chain")
}
}
@@ -205,7 +232,7 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
chainService := setupBeaconChain(t, db, sc)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := stateutil.BlockRoot(genesisBlk.Block)
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
@@ -213,10 +240,12 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
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[:]}))
// Test the start function.
chainService.Start()
require.DeepEqual(t, params.BeaconConfig().ZeroHash[:], chainService.finalizedCheckpt.Root, "Finalize Checkpoint root is incorrect")
require.DeepEqual(t, blkRoot[:], chainService.finalizedCheckpt.Root, "Finalize Checkpoint root is incorrect")
require.DeepEqual(t, params.BeaconConfig().ZeroHash[:], chainService.justifiedCheckpt.Root, "Justified Checkpoint root is incorrect")
require.NoError(t, chainService.Stop(), "Unable to stop chain service")
@@ -228,7 +257,7 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
ctx := context.Background()
genesis := testutil.NewBeaconBlock()
genesisRoot, err := stateutil.BlockRoot(genesis.Block)
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, genesis))
@@ -240,17 +269,12 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
headState := testutil.NewBeaconState()
require.NoError(t, headState.SetSlot(finalizedSlot))
require.NoError(t, headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]))
headRoot, err := stateutil.BlockRoot(headBlock.Block)
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))
if err := db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{
Epoch: helpers.SlotToEpoch(finalizedSlot),
Root: headRoot[:],
}); err != nil {
t.Fatal(err)
}
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, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
@@ -268,6 +292,37 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
}
func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
db, sc := 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))
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
headBlock := testutil.NewBeaconBlock()
headBlock.Block.Slot = finalizedSlot
headBlock.Block.ParentRoot = bytesutil.PadTo(genesisRoot[:], 32)
headState := testutil.NewBeaconState()
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, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(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)
}
func TestChainService_SaveHeadNoDB(t *testing.T) {
db, sc := testDB.SetupDB(t)
ctx := context.Background()
@@ -275,8 +330,9 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
beaconDB: db,
stateGen: stategen.New(db, sc),
}
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 1}}
r, err := ssz.HashTreeRoot(b)
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
r, err := b.HashTreeRoot()
require.NoError(t, err)
newState := testutil.NewBeaconState()
require.NoError(t, s.stateGen.SaveState(ctx, r, newState))
@@ -294,30 +350,45 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
db, _ := testDB.SetupDB(t)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
finalizedCheckpt: &ethpb.Checkpoint{},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: db,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}}
r, err := stateutil.BlockRoot(block.Block)
require.NoError(t, err)
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{}}
state, err := beaconstate.InitializeFromProto(bs)
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))
assert.Equal(t, false, s.hasBlock(ctx, [32]byte{}), "Should not have block")
assert.Equal(t, true, s.hasBlock(ctx, r), "Should have block")
}
func TestServiceStop_SaveCachedBlocks(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
db, _ := testDB.SetupDB(t)
s := &Service{
ctx: ctx,
cancel: cancel,
beaconDB: db,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
}
b := testutil.NewBeaconBlock()
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
s.saveInitSyncBlock(r, b)
require.NoError(t, s.Stop())
require.Equal(t, true, s.beaconDB.HasBlock(ctx, r))
}
func BenchmarkHasBlockDB(b *testing.B) {
db, _ := testDB.SetupDB(b)
ctx := context.Background()
s := &Service{
beaconDB: db,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
block := testutil.NewBeaconBlock()
require.NoError(b, s.beaconDB.SaveBlock(ctx, block))
r, err := stateutil.BlockRoot(block.Block)
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
b.ResetTimer()
@@ -331,13 +402,13 @@ func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
db, _ := testDB.SetupDB(b)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
finalizedCheckpt: &ethpb.Checkpoint{},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: db,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}}
r, err := stateutil.BlockRoot(block.Block)
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{}}
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}}
state, err := beaconstate.InitializeFromProto(bs)
require.NoError(b, err)
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, state))

View File

@@ -19,8 +19,8 @@ go_library(
"//beacon-chain/db:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/p2p/v1: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",

View File

@@ -19,8 +19,8 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
@@ -38,6 +38,7 @@ type ChainService struct {
Balance *precompute.Balance
Genesis time.Time
ValidatorsRoot [32]byte
CanonicalRoots map[[32]byte]bool
Fork *pb.Fork
ETH1Data *ethpb.Eth1Data
DB db.Database
@@ -80,7 +81,8 @@ func (msn *MockBlockNotifier) BlockFeed() *event.Feed {
// MockStateNotifier mocks the state notifier.
type MockStateNotifier struct {
feed *event.Feed
feed *event.Feed
feedLock sync.Mutex
recv []*feed.Event
recvLock sync.Mutex
@@ -98,6 +100,9 @@ func (msn *MockStateNotifier) ReceivedEvents() []*feed.Event {
// StateFeed returns a state feed.
func (msn *MockStateNotifier) StateFeed() *event.Feed {
msn.feedLock.Lock()
defer msn.feedLock.Unlock()
if msn.feed == nil && msn.recvCh == nil {
msn.feed = new(event.Feed)
if msn.RecordEvents {
@@ -141,7 +146,7 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
}
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
}
@@ -152,7 +157,7 @@ func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethp
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := stateutil.BlockRoot(block.Block)
signingRoot, err := block.Block.HashTreeRoot()
if err != nil {
return err
}
@@ -168,7 +173,7 @@ func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethp
}
// ReceiveBlockBatch processes blocks in batches from initial-sync.
func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, roots [][32]byte) error {
func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, _ [][32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
}
@@ -180,7 +185,7 @@ func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sig
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := stateutil.BlockRoot(block.Block)
signingRoot, err := block.Block.HashTreeRoot()
if err != nil {
return err
}
@@ -197,7 +202,7 @@ func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sig
}
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
}
@@ -208,7 +213,7 @@ func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBea
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := stateutil.BlockRoot(block.Block)
signingRoot, err := block.Block.HashTreeRoot()
if err != nil {
return err
}
@@ -232,9 +237,11 @@ func (ms *ChainService) HeadSlot() uint64 {
}
// HeadRoot mocks HeadRoot method in chain service.
func (ms *ChainService) HeadRoot(ctx context.Context) ([]byte, error) {
return ms.Root, nil
func (ms *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
if len(ms.Root) > 0 {
return ms.Root, nil
}
return make([]byte, 32), nil
}
// HeadBlock mocks HeadBlock method in chain service.
@@ -268,7 +275,7 @@ func (ms *ChainService) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
}
// ReceiveAttestation mocks ReceiveAttestation method in chain service.
func (ms *ChainService) ReceiveAttestation(context.Context, *ethpb.Attestation) error {
func (ms *ChainService) ReceiveAttestation(_ context.Context, _ *ethpb.Attestation) error {
return nil
}
@@ -278,12 +285,12 @@ func (ms *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attes
}
// AttestationPreState mocks AttestationPreState method in chain service.
func (ms *ChainService) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*stateTrie.BeaconState, error) {
func (ms *ChainService) AttestationPreState(_ context.Context, _ *ethpb.Attestation) (*stateTrie.BeaconState, error) {
return ms.State, nil
}
// HeadValidatorsIndices mocks the same method in the chain service.
func (ms *ChainService) HeadValidatorsIndices(ctx context.Context, epoch uint64) ([]uint64, error) {
func (ms *ChainService) HeadValidatorsIndices(_ context.Context, epoch uint64) ([]uint64, error) {
if ms.State == nil {
return []uint64{}, nil
}
@@ -291,7 +298,7 @@ func (ms *ChainService) HeadValidatorsIndices(ctx context.Context, epoch uint64)
}
// HeadSeed mocks the same method in the chain service.
func (ms *ChainService) HeadSeed(ctx context.Context, epoch uint64) ([32]byte, error) {
func (ms *ChainService) HeadSeed(_ context.Context, epoch uint64) ([32]byte, error) {
return helpers.Seed(ms.State, epoch, params.BeaconConfig().DomainBeaconAttester)
}
@@ -321,26 +328,27 @@ func (ms *ChainService) CurrentSlot() uint64 {
}
// Participation mocks the same method in the chain service.
func (ms *ChainService) Participation(epoch uint64) *precompute.Balance {
func (ms *ChainService) Participation(_ uint64) *precompute.Balance {
return ms.Balance
}
// IsValidAttestation always returns true.
func (ms *ChainService) IsValidAttestation(ctx context.Context, att *ethpb.Attestation) bool {
func (ms *ChainService) IsValidAttestation(_ context.Context, _ *ethpb.Attestation) bool {
return ms.ValidAttestation
}
// IsCanonical returns and determines whether a block with the provided root is part of
// the canonical chain.
func (ms *ChainService) IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error) {
func (ms *ChainService) IsCanonical(_ context.Context, r [32]byte) (bool, error) {
if ms.CanonicalRoots != nil {
_, ok := ms.CanonicalRoots[r]
return ok, nil
}
return true, nil
}
// ClearCachedStates does nothing.
func (ms *ChainService) ClearCachedStates() {}
// HasInitSyncBlock mocks the same method in the chain service.
func (ms *ChainService) HasInitSyncBlock(root [32]byte) bool {
func (ms *ChainService) HasInitSyncBlock(_ [32]byte) bool {
return false
}
@@ -350,6 +358,52 @@ func (ms *ChainService) HeadGenesisValidatorRoot() [32]byte {
}
// VerifyBlkDescendant mocks VerifyBlkDescendant and always returns nil.
func (ms *ChainService) VerifyBlkDescendant(ctx context.Context, root [32]byte) error {
func (ms *ChainService) VerifyBlkDescendant(_ context.Context, _ [32]byte) error {
return ms.VerifyBlkDescendantErr
}
// VerifyLmdFfgConsistency mocks VerifyLmdFfgConsistency and always returns nil.
func (ms *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")
}
return nil
}
// VerifyFinalizedConsistency mocks VerifyFinalizedConsistency and always returns nil.
func (ms *ChainService) VerifyFinalizedConsistency(_ context.Context, r []byte) error {
if !bytes.Equal(r, ms.FinalizedCheckPoint.Root) {
return errors.New("Root and finalized store are not consistent")
}
return nil
}
// AttestationCheckPtInfo mocks AttestationCheckPtInfo and always returns nil.
func (ms *ChainService) AttestationCheckPtInfo(_ context.Context, att *ethpb.Attestation) (*pb.CheckPtInfo, error) {
f := ms.State.Fork()
g := bytesutil.ToBytes32(ms.State.GenesisValidatorRoot())
seed, err := helpers.Seed(ms.State, helpers.SlotToEpoch(att.Data.Slot), params.BeaconConfig().DomainBeaconAttester)
if err != nil {
return nil, err
}
indices, err := helpers.ActiveValidatorIndices(ms.State, helpers.SlotToEpoch(att.Data.Slot))
if err != nil {
return nil, err
}
validators := ms.State.ValidatorsReadOnly()
pks := make([][]byte, len(validators))
for i := 0; i < len(pks); i++ {
pk := validators[i].PublicKey()
pks[i] = pk[:]
}
info := &pb.CheckPtInfo{
Fork: f,
GenesisRoot: g[:],
Seed: seed[:],
ActiveIndices: indices,
PubKeys: pks,
}
return info, nil
}

View File

@@ -0,0 +1,60 @@
package blockchain
import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// VerifyWeakSubjectivityRoot verifies the weak subjectivity root in the service struct.
// 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 {
return nil
}
// Do nothing if the weak subjectivity has previously been verified,
// or weak subjectivity epoch is higher than last finalized epoch.
if s.wsVerified {
return nil
}
if s.wsEpoch > 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)
// Save initial sync cached blocks to DB.
if err := s.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) {
return fmt.Errorf("node does not have root in DB: %#x", r)
}
startSlot, err := helpers.StartSlot(s.wsEpoch)
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)
if err != nil {
return err
}
for _, root := range roots {
if r == root {
log.Info("Weak subjectivity check has passed")
s.wsVerified = true
return nil
}
}
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.wsEpoch)
}

View File

@@ -0,0 +1,85 @@
package blockchain
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
db, _ := testDB.SetupDB(t)
b := testutil.NewBeaconBlock()
b.Block.Slot = 32
require.NoError(t, db.SaveBlock(context.Background(), b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
tests := []struct {
wsVerified bool
wantErr bool
wsRoot [32]byte
wsEpoch uint64
finalizedEpoch uint64
errString string
name string
}{
{
name: "nil root and epoch",
wantErr: false,
},
{
name: "already verified",
wsEpoch: 2,
finalizedEpoch: 2,
wsVerified: true,
wantErr: false,
},
{
name: "not yet to verify, ws epoch higher than finalized epoch",
wsEpoch: 2,
finalizedEpoch: 1,
wantErr: false,
},
{
name: "can't find the block in DB",
wsEpoch: 1,
wsRoot: [32]byte{'a'},
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.
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in db corresponding to epoch",
},
{
name: "can verify and pass",
wsEpoch: 1,
wsRoot: r,
finalizedEpoch: 3,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
beaconDB: db,
wsRoot: tt.wsRoot[:],
wsEpoch: tt.wsEpoch,
wsVerified: tt.wsVerified,
finalizedCheckpt: &ethpb.Checkpoint{Epoch: tt.finalizedEpoch},
}
if err := s.VerifyWeakSubjectivityRoot(context.Background()); (err != nil) != tt.wantErr {
require.ErrorContains(t, tt.errString, err)
}
})
}
}

View File

@@ -1,19 +1,31 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
# gazelle:ignore committee_disabled.go
# gazelle:ignore proposer_indices_disabled.go
go_library(
name = "go_default_library",
srcs = [
"attestation_data.go",
"checkpoint_state.go",
"committee.go",
"committees.go",
"common.go",
"doc.go",
"hot_state_cache.go",
"skip_slot_cache.go",
"state_summary.go",
"subnet_ids.go",
],
"proposer_indices_type.go",
] + select({
"//fuzz:fuzzing_enabled": [
"committee_disabled.go",
"proposer_indices_disabled.go"
],
"//conditions:default": [
"committee.go",
"proposer_indices.go",
],
}),
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/cache",
visibility = [
"//beacon-chain:__subpackages__",
@@ -49,6 +61,7 @@ go_test(
"hot_state_cache_test.go",
"skip_slot_cache_test.go",
"subnet_ids_test.go",
"proposer_indices_test.go"
],
embed = [":go_default_library"],
deps = [

View File

@@ -12,7 +12,6 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"k8s.io/client-go/tools/cache"
)
@@ -99,10 +98,7 @@ func (c *AttestationCache) Get(ctx context.Context, req *ethpb.AttestationDataRe
if exists && item != nil && item.(*attestationReqResWrapper).res != nil {
attestationCacheHit.Inc()
if featureconfig.Get().ReduceAttesterStateCopy {
return state.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
}
return item.(*attestationReqResWrapper).res, nil
return state.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
}
attestationCacheMiss.Inc()
return nil, nil
@@ -138,7 +134,7 @@ func (c *AttestationCache) MarkNotInProgress(req *ethpb.AttestationDataRequest)
}
// Put the response in the cache.
func (c *AttestationCache) Put(ctx context.Context, req *ethpb.AttestationDataRequest, res *ethpb.AttestationData) error {
func (c *AttestationCache) Put(_ context.Context, req *ethpb.AttestationDataRequest, res *ethpb.AttestationData) error {
data := &attestationReqResWrapper{
req,
res,
@@ -167,10 +163,7 @@ func wrapperToKey(i interface{}) (string, error) {
}
func reqToKey(req *ethpb.AttestationDataRequest) (string, error) {
if featureconfig.Get().ReduceAttesterStateCopy {
return fmt.Sprintf("%d", req.Slot), nil
}
return fmt.Sprintf("%d-%d", req.CommitteeIndex, req.Slot), nil
return fmt.Sprintf("%d", req.Slot), nil
}
type attestationReqResWrapper struct {

View File

@@ -26,7 +26,7 @@ func TestAttestationCache_RoundTrip(t *testing.T) {
assert.NoError(t, c.MarkInProgress(req))
res := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 5},
Target: &ethpb.Checkpoint{Epoch: 5, Root: make([]byte, 32)},
}
assert.NoError(t, c.Put(ctx, req, res))

View File

@@ -1,8 +1,10 @@
package cache
import (
"errors"
"context"
"math"
"sync"
"time"
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
@@ -13,10 +15,6 @@ import (
)
var (
// ErrNotCheckpointState will be returned when a cache object is not a pointer to
// a CheckpointState struct.
ErrNotCheckpointState = errors.New("object is not a state by check point struct")
// maxCheckpointStateSize defines the max number of entries check point to state cache can contain.
// Choosing 10 to account for multiple forks, this allows 5 forks per epoch boundary with 2 epochs
// window to accept attestation based on latest spec.
@@ -35,8 +33,9 @@ var (
// CheckpointStateCache is a struct with 1 queue for looking up state by checkpoint.
type CheckpointStateCache struct {
cache *lru.Cache
lock sync.RWMutex
cache *lru.Cache
lock sync.RWMutex
inProgress map[string]bool
}
// NewCheckpointStateCache creates a new checkpoint state cache for storing/accessing processed state.
@@ -46,22 +45,45 @@ func NewCheckpointStateCache() *CheckpointStateCache {
panic(err)
}
return &CheckpointStateCache{
cache: cache,
cache: cache,
inProgress: map[string]bool{},
}
}
// 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) {
c.lock.RLock()
defer c.lock.RUnlock()
h, err := hashutil.HashProto(cp)
func (c *CheckpointStateCache) StateByCheckpoint(ctx context.Context, cp *ethpb.Checkpoint) (*stateTrie.BeaconState, error) {
k, err := checkpointKey(cp)
if err != nil {
return nil, err
}
item, exists := c.cache.Get(h)
delay := minDelay
// Another identical request may be in progress already. Let's wait until
// any in progress request resolves or our timeout is exceeded.
for {
if ctx.Err() != nil {
return nil, ctx.Err()
}
c.lock.RLock()
if !c.inProgress[k] {
c.lock.RUnlock()
break
}
c.lock.RUnlock()
// This increasing backoff is to decrease the CPU cycles while waiting
// for the in progress boolean to flip to false.
time.Sleep(time.Duration(delay) * time.Nanosecond)
delay *= delayFactor
delay = math.Min(delay, maxDelay)
}
c.lock.RLock()
defer c.lock.RUnlock()
item, exists := c.cache.Get(k)
if exists && item != nil {
checkpointStateHit.Inc()
// Copy here is unnecessary since the return will only be used to verify attestation signature.
@@ -77,10 +99,47 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s *stateTrie.BeaconState) error {
c.lock.Lock()
defer c.lock.Unlock()
h, err := hashutil.HashProto(cp)
k, err := checkpointKey(cp)
if err != nil {
return err
}
c.cache.Add(h, s)
c.cache.ContainsOrAdd(k, s)
return nil
}
// MarkInProgress a request so that any other similar requests will block on
// Get until MarkNotInProgress is called.
func (c *CheckpointStateCache) MarkInProgress(cp *ethpb.Checkpoint) error {
c.lock.Lock()
defer c.lock.Unlock()
k, err := checkpointKey(cp)
if err != nil {
return err
}
if c.inProgress[k] {
return ErrAlreadyInProgress
}
c.inProgress[k] = true
return nil
}
// MarkNotInProgress will release the lock on a given request. This should be
// called after put.
func (c *CheckpointStateCache) MarkNotInProgress(cp *ethpb.Checkpoint) error {
c.lock.Lock()
defer c.lock.Unlock()
k, err := checkpointKey(cp)
if err != nil {
return err
}
delete(c.inProgress, k)
return nil
}
func checkpointKey(cp *ethpb.Checkpoint) (string, error) {
h, err := hashutil.HashProto(cp)
if err != nil {
return "", err
}
return string(h[:]), nil
}

View File

@@ -1,6 +1,7 @@
package cache
import (
"context"
"testing"
"github.com/gogo/protobuf/proto"
@@ -23,13 +24,13 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
})
require.NoError(t, err)
state, err := cache.StateByCheckpoint(cp1)
state, err := cache.StateByCheckpoint(context.Background(), cp1)
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Expected state not to exist in empty cache")
require.NoError(t, cache.AddCheckpointState(cp1, st))
state, err = cache.StateByCheckpoint(cp1)
state, err = cache.StateByCheckpoint(context.Background(), cp1)
require.NoError(t, err)
if !proto.Equal(state.InnerStateUnsafe(), st.InnerStateUnsafe()) {
@@ -43,11 +44,11 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
require.NoError(t, err)
require.NoError(t, cache.AddCheckpointState(cp2, st2))
state, err = cache.StateByCheckpoint(cp2)
state, err = cache.StateByCheckpoint(context.Background(), cp2)
require.NoError(t, err)
assert.DeepEqual(t, st2.CloneInnerState(), state.CloneInnerState(), "incorrectly cached state")
state, err = cache.StateByCheckpoint(cp1)
state, err = cache.StateByCheckpoint(context.Background(), cp1)
require.NoError(t, err)
assert.DeepEqual(t, st.CloneInnerState(), state.CloneInnerState(), "incorrectly cached state")
}
@@ -61,7 +62,7 @@ func TestCheckpointStateCache_MaxSize(t *testing.T) {
for i := uint64(0); i < uint64(maxCheckpointStateSize+100); i++ {
require.NoError(t, st.SetSlot(i))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: i}, st))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: i, Root: make([]byte, 32)}, st))
}
assert.Equal(t, maxCheckpointStateSize, len(c.cache.Keys()))

View File

@@ -1,3 +1,5 @@
// +build !libfuzzer
package cache
import (
@@ -12,10 +14,6 @@ import (
)
var (
// ErrNotCommittee will be returned when a cache object is not a pointer to
// a Committee struct.
ErrNotCommittee = errors.New("object is not a committee struct")
// maxCommitteesCacheSize defines the max number of shuffled committees on per randao basis can cache.
// Due to reorgs and long finality, it's good to keep the old cache around for quickly switch over.
maxCommitteesCacheSize = uint64(32)
@@ -32,15 +30,6 @@ var (
})
)
// Committees defines the shuffled committees seed.
type Committees struct {
CommitteeCount uint64
Seed [32]byte
ShuffledIndices []uint64
SortedIndices []uint64
ProposerIndices []uint64
}
// CommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type CommitteeCache struct {
CommitteeCache *cache.FIFO
@@ -115,35 +104,6 @@ func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error
return nil
}
// AddProposerIndicesList updates the committee shuffled list with proposer indices.
func (c *CommitteeCache) AddProposerIndicesList(seed [32]byte, indices []uint64) error {
c.lock.Lock()
defer c.lock.Unlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return err
}
if !exists {
committees := &Committees{ProposerIndices: indices}
if err := c.CommitteeCache.Add(committees); err != nil {
return err
}
} else {
committees, ok := obj.(*Committees)
if !ok {
return ErrNotCommittee
}
committees.ProposerIndices = indices
if err := c.CommitteeCache.Add(committees); err != nil {
return err
}
}
trim(c.CommitteeCache, maxCommitteesCacheSize)
return nil
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
c.lock.RLock()
@@ -192,28 +152,10 @@ func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
return len(item.SortedIndices), nil
}
// ProposerIndices returns the proposer indices of a given seed.
func (c *CommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return nil, err
}
if exists {
CommitteeCacheHit.Inc()
} else {
CommitteeCacheMiss.Inc()
return nil, nil
}
item, ok := obj.(*Committees)
if !ok {
return nil, ErrNotCommittee
}
return item.ProposerIndices, nil
// 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
}
func startEndIndices(c *Committees, index uint64) (uint64, uint64) {

View File

@@ -0,0 +1,50 @@
// +build libfuzzer
// This file is used in fuzzer builds to bypass global committee caches.
package cache
// FakeCommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type FakeCommitteeCache struct {
}
// NewCommitteesCache creates a new committee cache for storing/accessing shuffled indices of a committee.
func NewCommitteesCache() *FakeCommitteeCache {
return &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) {
return nil, nil
}
// AddCommitteeShuffledList adds Committee shuffled list object to the cache. T
// his method also trims the least recently list if the cache size has ready the max cache size limit.
func (c *FakeCommitteeCache) AddCommitteeShuffledList(committees *Committees) error {
return nil
}
// AddProposerIndicesList updates the committee shuffled list with proposer indices.
func (c *FakeCommitteeCache) AddProposerIndicesList(seed [32]byte, indices []uint64) error {
return nil
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *FakeCommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
return nil, nil
}
// ActiveIndicesCount returns the active indices count of a given seed stored in cache.
func (c *FakeCommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
return 0, nil
}
// ProposerIndices returns the proposer indices of a given seed.
func (c *FakeCommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
return nil, nil
}
// HasEntry returns true if the committee cache has a value.
func (c *FakeCommitteeCache) HasEntry(string) bool {
return false
}

View File

@@ -87,37 +87,6 @@ func TestCommitteeCache_ActiveCount(t *testing.T) {
assert.Equal(t, len(item.SortedIndices), count)
}
func TestCommitteeCache_AddProposerIndicesList(t *testing.T) {
cache := NewCommitteesCache()
seed := [32]byte{'A'}
indices := []uint64{1, 2, 3, 4, 5}
indices, err := cache.ProposerIndices(seed)
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
require.NoError(t, cache.AddProposerIndicesList(seed, indices))
received, err := cache.ProposerIndices(seed)
require.NoError(t, err)
assert.DeepEqual(t, received, indices)
item := &Committees{Seed: [32]byte{'B'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
require.NoError(t, cache.AddCommitteeShuffledList(item))
indices, err = cache.ProposerIndices(item.Seed)
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
require.NoError(t, cache.AddProposerIndicesList(item.Seed, indices))
received, err = cache.ProposerIndices(item.Seed)
require.NoError(t, err)
assert.DeepEqual(t, received, indices)
}
func TestCommitteeCache_CanRotate(t *testing.T) {
cache := NewCommitteesCache()
@@ -152,7 +121,6 @@ func TestCommitteeCacheOutOfRange(t *testing.T) {
Seed: seed,
ShuffledIndices: []uint64{0},
SortedIndices: []uint64{},
ProposerIndices: []uint64{},
})
require.NoError(t, err)

15
beacon-chain/cache/committees.go vendored Normal file
View File

@@ -0,0 +1,15 @@
package cache
import "errors"
// ErrNotCommittee will be returned when a cache object is not a pointer to
// a Committee struct.
var ErrNotCommittee = errors.New("object is not a committee struct")
// Committees defines the shuffled committees seed.
type Committees struct {
CommitteeCount uint64
Seed [32]byte
ShuffledIndices []uint64
SortedIndices []uint64
}

View File

@@ -24,6 +24,6 @@ func trim(queue *cache.FIFO, maxSize uint64) {
}
// popProcessNoopFunc is a no-op function that never returns an error.
func popProcessNoopFunc(obj interface{}) error {
func popProcessNoopFunc(_ interface{}) error {
return nil
}

View File

@@ -18,7 +18,6 @@ go_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_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
@@ -40,7 +39,6 @@ go_test(
"//shared/trieutil: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//hooks/test:go_default_library",
],
)

View File

@@ -15,7 +15,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -51,17 +50,17 @@ type FinalizedDeposits struct {
// stores all the deposit related data that is required by the beacon-node.
type DepositCache struct {
// Beacon chain deposits in memory.
pendingDeposits []*dbpb.DepositContainer
deposits []*dbpb.DepositContainer
finalizedDeposits *FinalizedDeposits
depositsLock sync.RWMutex
chainStartDeposits []*ethpb.Deposit
chainStartPubkeys map[string]bool
pendingDeposits []*dbpb.DepositContainer
deposits []*dbpb.DepositContainer
finalizedDeposits *FinalizedDeposits
depositsLock sync.RWMutex
chainStartPubkeys map[string]bool
chainStartPubkeysLock sync.RWMutex
}
// NewDepositCache instantiates a new deposit cache
func NewDepositCache() (*DepositCache, error) {
finalizedDepositsTrie, err := trieutil.NewTrie(int(params.BeaconConfig().DepositContractTreeDepth))
// New instantiates a new deposit cache
func New() (*DepositCache, error) {
finalizedDepositsTrie, err := trieutil.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
if err != nil {
return nil, err
}
@@ -69,11 +68,10 @@ func NewDepositCache() (*DepositCache, error) {
// finalizedDeposits.MerkleTrieIndex is initialized to -1 because it represents the index of the last trie item.
// Inserting the first item into the trie will set the value of the index to 0.
return &DepositCache{
pendingDeposits: []*dbpb.DepositContainer{},
deposits: []*dbpb.DepositContainer{},
finalizedDeposits: &FinalizedDeposits{Deposits: finalizedDepositsTrie, MerkleTrieIndex: -1},
chainStartPubkeys: make(map[string]bool),
chainStartDeposits: make([]*ethpb.Deposit, 0),
pendingDeposits: []*dbpb.DepositContainer{},
deposits: []*dbpb.DepositContainer{},
finalizedDeposits: &FinalizedDeposits{Deposits: finalizedDepositsTrie, MerkleTrieIndex: -1},
chainStartPubkeys: make(map[string]bool),
}, nil
}
@@ -120,7 +118,7 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
defer dc.depositsLock.Unlock()
depositTrie := dc.finalizedDeposits.Deposits
insertIndex := dc.finalizedDeposits.MerkleTrieIndex + 1
insertIndex := int(dc.finalizedDeposits.MerkleTrieIndex + 1)
for _, d := range dc.deposits {
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
continue
@@ -128,12 +126,12 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
if d.Index > eth1DepositIndex {
break
}
depHash, err := ssz.HashTreeRoot(d.Deposit.Data)
depHash, err := d.Deposit.Data.HashTreeRoot()
if err != nil {
log.WithError(err).Error("Could not hash deposit data. Finalized deposit cache not updated.")
return
}
depositTrie.Insert(depHash[:], int(insertIndex))
depositTrie.Insert(depHash[:], insertIndex)
insertIndex++
}
@@ -157,6 +155,8 @@ func (dc *DepositCache) AllDepositContainers(ctx context.Context) []*dbpb.Deposi
func (dc *DepositCache) MarkPubkeyForChainstart(ctx context.Context, pubkey string) {
ctx, span := trace.StartSpan(ctx, "DepositsCache.MarkPubkeyForChainstart")
defer span.End()
dc.chainStartPubkeysLock.Lock()
defer dc.chainStartPubkeysLock.Unlock()
dc.chainStartPubkeys[pubkey] = true
}
@@ -164,6 +164,8 @@ func (dc *DepositCache) MarkPubkeyForChainstart(ctx context.Context, pubkey stri
func (dc *DepositCache) PubkeyInChainstart(ctx context.Context, pubkey string) bool {
ctx, span := trace.StartSpan(ctx, "DepositsCache.PubkeyInChainstart")
defer span.End()
dc.chainStartPubkeysLock.RLock()
defer dc.chainStartPubkeysLock.RUnlock()
if dc.chainStartPubkeys != nil {
return dc.chainStartPubkeys[pubkey]
}
@@ -259,3 +261,28 @@ func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, untilBlk *big.
return deposits
}
// PruneProofs removes proofs from all deposits whose index is equal or less than untilDepositIndex.
func (dc *DepositCache) PruneProofs(ctx context.Context, untilDepositIndex int64) error {
ctx, span := trace.StartSpan(ctx, "DepositsCache.PruneProofs")
defer span.End()
dc.depositsLock.Lock()
defer dc.depositsLock.Unlock()
if untilDepositIndex > int64(len(dc.deposits)) {
untilDepositIndex = int64(len(dc.deposits) - 1)
}
for i := untilDepositIndex; i >= 0; i-- {
if ctx.Err() != nil {
return ctx.Err()
}
// Finding a nil proof means that all proofs up to this deposit have been already pruned.
if dc.deposits[i].Deposit.Proof == nil {
break
}
dc.deposits[i].Deposit.Proof = nil
}
return nil
}

View File

@@ -8,7 +8,6 @@ import (
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -20,11 +19,11 @@ import (
const nilDepositErr = "Ignoring nil deposit insertion"
var _ = DepositFetcher(&DepositCache{})
var _ DepositFetcher = (*DepositCache)(nil)
func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
hook := logTest.NewGlobal()
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{})
@@ -34,7 +33,7 @@ func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
}
func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
insertions := []struct {
@@ -76,7 +75,7 @@ func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
}
func TestAllDeposits_ReturnsAllDeposits(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
deposits := []*dbpb.DepositContainer{
@@ -116,7 +115,7 @@ func TestAllDeposits_ReturnsAllDeposits(t *testing.T) {
}
func TestAllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
deposits := []*dbpb.DepositContainer{
@@ -156,38 +155,80 @@ func TestAllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
}
func TestDepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
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{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
}
@@ -197,19 +238,31 @@ func TestDepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing
}
func TestDepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOldestDeposit(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
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: 11,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
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),
},
}
@@ -219,7 +272,7 @@ func TestDepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOlde
}
func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
@@ -227,7 +280,9 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
Eth1BlockHeight: 9,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk0"),
PublicKey: bytesutil.PadTo([]byte("pk0"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
@@ -235,7 +290,9 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk1"),
PublicKey: bytesutil.PadTo([]byte("pk1"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
@@ -243,7 +300,9 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk1"),
PublicKey: bytesutil.PadTo([]byte("pk1"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
@@ -251,15 +310,18 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk2"),
PublicKey: bytesutil.PadTo([]byte("pk2"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
}
dep, blkNum := dc.DepositByPubkey(context.Background(), []byte("pk1"))
pk1 := bytesutil.PadTo([]byte("pk1"), 48)
dep, blkNum := dc.DepositByPubkey(context.Background(), pk1)
if !bytes.Equal(dep.Data.PublicKey, []byte("pk1")) {
if dep == nil || !bytes.Equal(dep.Data.PublicKey, pk1) {
t.Error("Returned wrong deposit")
}
assert.Equal(t, 0, blkNum.Cmp(big.NewInt(10)),
@@ -267,14 +329,16 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
}
func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{0},
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
@@ -282,7 +346,9 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{1},
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
@@ -290,7 +356,9 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{2},
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
@@ -299,7 +367,9 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
dc.deposits = append(finalizedDeposits, &dbpb.DepositContainer{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{3},
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
@@ -313,24 +383,26 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
var deps [][]byte
for _, d := range finalizedDeposits {
hash, err := ssz.HashTreeRoot(d.Deposit.Data)
hash, err := d.Deposit.Data.HashTreeRoot()
require.NoError(t, err, "Could not hash deposit data")
deps = append(deps, hash[:])
}
trie, err := trieutil.GenerateTrieFromItems(deps, int(params.BeaconConfig().DepositContractTreeDepth))
trie, err := trieutil.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate deposit trie")
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
}
func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
oldFinalizedDeposits := []*dbpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{0},
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
@@ -338,7 +410,9 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{1},
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
@@ -347,7 +421,9 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
newFinalizedDeposit := dbpb.DepositContainer{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{2},
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
@@ -365,17 +441,17 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
var deps [][]byte
for _, d := range append(oldFinalizedDeposits, &newFinalizedDeposit) {
hash, err := ssz.HashTreeRoot(d.Deposit.Data)
hash, err := d.Deposit.Data.HashTreeRoot()
require.NoError(t, err, "Could not hash deposit data")
deps = append(deps, hash[:])
}
trie, err := trieutil.GenerateTrieFromItems(deps, int(params.BeaconConfig().DepositContractTreeDepth))
trie, err := trieutil.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate deposit trie")
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
}
func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
finalizedDeposits := dc.finalizedDeposits
@@ -385,7 +461,7 @@ func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
}
func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
@@ -393,7 +469,9 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{0},
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
@@ -402,7 +480,9 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{1},
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
@@ -413,7 +493,9 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{2},
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
@@ -422,7 +504,9 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{3},
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
@@ -434,7 +518,7 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
}
func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *testing.T) {
dc, err := NewDepositCache()
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
@@ -442,7 +526,9 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{0},
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
@@ -451,7 +537,9 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{1},
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
@@ -462,7 +550,9 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{2},
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
@@ -471,7 +561,9 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{3},
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
@@ -481,3 +573,137 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
deps := dc.NonFinalizedDeposits(context.Background(), big.NewInt(10))
assert.Equal(t, 1, len(deps))
}
func TestPruneProofs_Ok(t *testing.T) {
dc, err := New()
require.NoError(t, err)
deposits := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
},
}
for _, ins := range deposits {
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.NotNil(t, dc.deposits[2].Deposit.Proof)
assert.NotNil(t, dc.deposits[3].Deposit.Proof)
}
func TestPruneProofs_SomeAlreadyPruned(t *testing.T) {
dc, err := New()
require.NoError(t, err)
deposits := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
},
}
for _, ins := range deposits {
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)
}
func TestPruneProofs_PruneAllWhenDepositIndexTooBig(t *testing.T) {
dc, err := New()
require.NoError(t, err)
deposits := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
},
}
for _, ins := range deposits {
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)
}
func makeDepositProof() [][]byte {
proof := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
for i := range proof {
proof[i] = make([]byte, 32)
}
return proof
}

View File

@@ -9,11 +9,10 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
)
var _ = PendingDepositsFetcher(&DepositCache{})
var _ PendingDepositsFetcher = (*DepositCache)(nil)
func TestInsertPendingDeposit_OK(t *testing.T) {
dc := DepositCache{}
@@ -31,12 +30,18 @@ func TestInsertPendingDeposit_ignoresNilDeposit(t *testing.T) {
func TestRemovePendingDeposit_OK(t *testing.T) {
db := DepositCache{}
proof1 := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
proof1 := makeDepositProof()
proof1[0] = bytesutil.PadTo([]byte{'A'}, 32)
proof2 := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
proof2 := makeDepositProof()
proof2[0] = bytesutil.PadTo([]byte{'A'}, 32)
depToRemove := &ethpb.Deposit{Proof: proof1}
otherDep := &ethpb.Deposit{Proof: proof2}
data := &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Amount: 0,
Signature: make([]byte, 96),
}
depToRemove := &ethpb.Deposit{Proof: proof1, Data: data}
otherDep := &ethpb.Deposit{Proof: proof2, Data: data}
db.pendingDeposits = []*dbpb.DepositContainer{
{Deposit: depToRemove, Index: 1},
{Deposit: otherDep, Index: 5},
@@ -57,9 +62,15 @@ func TestRemovePendingDeposit_IgnoresNilDeposit(t *testing.T) {
func TestPendingDeposit_RoundTrip(t *testing.T) {
dc := DepositCache{}
proof := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
proof := makeDepositProof()
proof[0] = bytesutil.PadTo([]byte{'A'}, 32)
dep := &ethpb.Deposit{Proof: proof}
data := &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Amount: 0,
Signature: make([]byte, 96),
}
dep := &ethpb.Deposit{Proof: proof, Data: data}
dc.InsertPendingDeposit(context.Background(), dep, 111, 100, [32]byte{})
dc.RemovePendingDeposit(context.Background(), dep)
assert.Equal(t, 0, len(dc.pendingDeposits), "Failed to insert & delete a pending deposit")

View File

@@ -10,5 +10,8 @@ import (
func TestMain(m *testing.M) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{EnableEth1DataVoteCache: true})
defer resetCfg()
os.Exit(m.Run())
code := m.Run()
// os.Exit will prevent defer from being called
resetCfg()
os.Exit(code)
}

88
beacon-chain/cache/proposer_indices.go vendored Normal file
View File

@@ -0,0 +1,88 @@
// +build !libfuzzer
package cache
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"k8s.io/client-go/tools/cache"
)
var (
// maxProposerIndicesCacheSize defines the max number of proposer indices on per block root basis can cache.
// Due to reorgs and long finality, it's good to keep the old cache around for quickly switch over.
maxProposerIndicesCacheSize = uint64(8)
// ProposerIndicesCacheMiss tracks the number of proposerIndices requests that aren't present in the cache.
ProposerIndicesCacheMiss = promauto.NewCounter(prometheus.CounterOpts{
Name: "proposer_indices_cache_miss",
Help: "The number of proposer indices requests that aren't present in the cache.",
})
// ProposerIndicesCacheHit tracks the number of proposerIndices requests that are in the cache.
ProposerIndicesCacheHit = promauto.NewCounter(prometheus.CounterOpts{
Name: "proposer_indices_cache_hit",
Help: "The number of proposer indices requests that are present in the cache.",
})
)
// ProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
type ProposerIndicesCache struct {
ProposerIndicesCache *cache.FIFO
lock sync.RWMutex
}
// proposerIndicesKeyFn takes the block root as the key to retrieve proposer indices in a given epoch.
func proposerIndicesKeyFn(obj interface{}) (string, error) {
info, ok := obj.(*ProposerIndices)
if !ok {
return "", ErrNotProposerIndices
}
return key(info.BlockRoot), nil
}
// NewProposerIndicesCache creates a new proposer indices cache for storing/accessing proposer index assignments of an epoch.
func NewProposerIndicesCache() *ProposerIndicesCache {
return &ProposerIndicesCache{
ProposerIndicesCache: cache.NewFIFO(proposerIndicesKeyFn),
}
}
// AddProposerIndices adds ProposerIndices object to the cache.
// This method also trims the least recently list if the cache size has ready the max cache size limit.
func (c *ProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.ProposerIndicesCache.AddIfNotPresent(p); err != nil {
return err
}
trim(c.ProposerIndicesCache, maxProposerIndicesCacheSize)
return nil
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.ProposerIndicesCache.GetByKey(key(r))
if err != nil {
return nil, err
}
if exists {
ProposerIndicesCacheHit.Inc()
} else {
ProposerIndicesCacheMiss.Inc()
return nil, nil
}
item, ok := obj.(*ProposerIndices)
if !ok {
return nil, ErrNotProposerIndices
}
return item.ProposerIndices, nil
}

View File

@@ -0,0 +1,24 @@
// +build libfuzzer
// This file is used in fuzzer builds to bypass proposer indices caches.
package cache
// FakeProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
type FakeProposerIndicesCache struct {
}
// NewProposerIndicesCache creates a new proposer indices cache for storing/accessing proposer index assignments of an epoch.
func NewProposerIndicesCache() *FakeProposerIndicesCache {
return &FakeProposerIndicesCache{}
}
// AddProposerIndices adds ProposerIndices object to the cache.
// This method also trims the least recently list if the cache size has ready the max cache size limit.
func (c *FakeProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error {
return nil
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
return nil, nil
}

View File

@@ -0,0 +1,63 @@
package cache
import (
"strconv"
"testing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProposerKeyFn_OK(t *testing.T) {
item := &ProposerIndices{
BlockRoot: [32]byte{'A'},
ProposerIndices: []uint64{1, 2, 3, 4, 5},
}
k, err := proposerIndicesKeyFn(item)
require.NoError(t, err)
assert.Equal(t, key(item.BlockRoot), k)
}
func TestProposerKeyFn_InvalidObj(t *testing.T) {
_, err := proposerIndicesKeyFn("bad")
assert.Equal(t, ErrNotProposerIndices, err)
}
func TestProposerCache_AddProposerIndicesList(t *testing.T) {
cache := NewProposerIndicesCache()
bRoot := [32]byte{'A'}
indices, err := cache.ProposerIndices(bRoot)
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
require.NoError(t, cache.AddProposerIndices(&ProposerIndices{
ProposerIndices: indices,
BlockRoot: bRoot,
}))
received, err := cache.ProposerIndices(bRoot)
require.NoError(t, err)
assert.DeepEqual(t, received, indices)
item := &ProposerIndices{BlockRoot: [32]byte{'B'}, ProposerIndices: []uint64{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)
}
func TestProposerCache_CanRotate(t *testing.T) {
cache := NewProposerIndicesCache()
for i := 0; i < int(maxProposerIndicesCacheSize)+1; i++ {
s := []byte(strconv.Itoa(i))
item := &ProposerIndices{BlockRoot: bytesutil.ToBytes32(s)}
require.NoError(t, cache.AddProposerIndices(item))
}
k := cache.ProposerIndicesCache.ListKeys()
assert.Equal(t, maxProposerIndicesCacheSize, uint64(len(k)))
}

View File

@@ -0,0 +1,13 @@
package cache
import "errors"
// ErrNotProposerIndices will be returned when a cache object is not a pointer to
// a ProposerIndices struct.
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
}

View File

@@ -30,7 +30,7 @@ type SkipSlotCache struct {
cache *lru.Cache
lock sync.RWMutex
disabled bool // Allow for programmatic toggling of the cache, useful during initial sync.
inProgress map[uint64]bool
inProgress map[[32]byte]bool
}
// NewSkipSlotCache initializes the map and underlying cache.
@@ -41,7 +41,7 @@ func NewSkipSlotCache() *SkipSlotCache {
}
return &SkipSlotCache{
cache: cache,
inProgress: make(map[uint64]bool),
inProgress: make(map[[32]byte]bool),
}
}
@@ -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, slot uint64) (*stateTrie.BeaconState, error) {
func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "skipSlotCache.Get")
defer span.End()
if c.disabled {
@@ -77,7 +77,7 @@ func (c *SkipSlotCache) Get(ctx context.Context, slot uint64) (*stateTrie.Beacon
}
c.lock.RLock()
if !c.inProgress[slot] {
if !c.inProgress[r] {
c.lock.RUnlock()
break
}
@@ -92,7 +92,7 @@ func (c *SkipSlotCache) Get(ctx context.Context, slot uint64) (*stateTrie.Beacon
}
span.AddAttributes(trace.BoolAttribute("inProgress", inProgress))
item, exists := c.cache.Get(slot)
item, exists := c.cache.Get(r)
if exists && item != nil {
skipSlotCacheHit.Inc()
@@ -106,7 +106,7 @@ func (c *SkipSlotCache) Get(ctx context.Context, slot uint64) (*stateTrie.Beacon
// MarkInProgress a request so that any other similar requests will block on
// Get until MarkNotInProgress is called.
func (c *SkipSlotCache) MarkInProgress(slot uint64) error {
func (c *SkipSlotCache) MarkInProgress(r [32]byte) error {
if c.disabled {
return nil
}
@@ -114,16 +114,16 @@ func (c *SkipSlotCache) MarkInProgress(slot uint64) error {
c.lock.Lock()
defer c.lock.Unlock()
if c.inProgress[slot] {
if c.inProgress[r] {
return ErrAlreadyInProgress
}
c.inProgress[slot] = true
c.inProgress[r] = true
return nil
}
// MarkNotInProgress will release the lock on a given request. This should be
// called after put.
func (c *SkipSlotCache) MarkNotInProgress(slot uint64) error {
func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) error {
if c.disabled {
return nil
}
@@ -131,18 +131,18 @@ func (c *SkipSlotCache) MarkNotInProgress(slot uint64) error {
c.lock.Lock()
defer c.lock.Unlock()
delete(c.inProgress, slot)
delete(c.inProgress, r)
return nil
}
// Put the response in the cache.
func (c *SkipSlotCache) Put(ctx context.Context, slot uint64, state *stateTrie.BeaconState) error {
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state *stateTrie.BeaconState) error {
if c.disabled {
return nil
}
// Copy state so cached value is not mutated.
c.cache.Add(slot, state.Copy())
c.cache.Add(r, state.Copy())
return nil
}

View File

@@ -15,21 +15,22 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
ctx := context.Background()
c := cache.NewSkipSlotCache()
state, err := c.Get(ctx, 5)
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")
require.NoError(t, c.MarkInProgress(5))
require.NoError(t, c.MarkInProgress(r))
state, err = stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
require.NoError(t, err)
require.NoError(t, c.Put(ctx, 5, state))
require.NoError(t, c.MarkNotInProgress(5))
require.NoError(t, c.Put(ctx, r, state))
require.NoError(t, c.MarkNotInProgress(r))
res, err := c.Get(ctx, 5)
res, err := c.Get(ctx, r)
require.NoError(t, err)
assert.DeepEqual(t, res.CloneInnerState(), state.CloneInnerState(), "Expected equal protos to return from cache")
}

View File

@@ -50,11 +50,11 @@ func (s *StateSummaryCache) GetAll() []*pb.StateSummary {
s.initSyncStateSummariesLock.RLock()
defer s.initSyncStateSummariesLock.RUnlock()
blks := make([]*pb.StateSummary, 0, len(s.initSyncStateSummaries))
summaries := make([]*pb.StateSummary, 0, len(s.initSyncStateSummaries))
for _, b := range s.initSyncStateSummaries {
blks = append(blks, b)
summaries = append(summaries, b)
}
return blks
return summaries
}
// Clear clears out the initial sync state summaries cache.

View File

@@ -25,12 +25,12 @@ 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 := params.BeaconConfig().MaxCommitteesPerSlot * params.BeaconConfig().SlotsPerEpoch * 2
attesterCache, err := lru.New(int(cacheSize))
cacheSize := int(params.BeaconConfig().MaxCommitteesPerSlot * params.BeaconConfig().SlotsPerEpoch * 2)
attesterCache, err := lru.New(cacheSize)
if err != nil {
panic(err)
}
aggregatorCache, err := lru.New(int(cacheSize))
aggregatorCache, err := lru.New(cacheSize)
if err != nil {
panic(err)
}
@@ -41,7 +41,7 @@ func newSubnetIDs() *subnetIDs {
}
// AddAttesterSubnetID adds the subnet index for subscribing subnet for the attester of a given slot.
func (c *subnetIDs) AddAttesterSubnetID(slot uint64, subnetID uint64) {
func (c *subnetIDs) AddAttesterSubnetID(slot, subnetID uint64) {
c.attesterLock.Lock()
defer c.attesterLock.Unlock()
@@ -69,7 +69,7 @@ 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 uint64, subnetID uint64) {
func (c *subnetIDs) AddAggregatorSubnetID(slot, subnetID uint64) {
c.aggregatorLock.Lock()
defer c.aggregatorLock.Unlock()
@@ -113,7 +113,7 @@ func (c *subnetIDs) GetAllSubnets() []uint64 {
defer c.subnetsLock.RUnlock()
itemsMap := c.persistentSubnets.Items()
committees := []uint64{}
var committees []uint64
for _, v := range itemsMap {
if v.Expired() {

View File

@@ -42,12 +42,10 @@ func TestSubnetIDsCache_RoundTrip(t *testing.T) {
}
func TestSubnetIDsCache_PersistentCommitteeRoundtrip(t *testing.T) {
pubkeySet := [][48]byte{}
c := newSubnetIDs()
for i := 0; i < 20; i++ {
pubkey := [48]byte{byte(i)}
pubkeySet = append(pubkeySet, pubkey)
c.AddPersistentCommittee(pubkey[:], []uint64{uint64(i)}, 0)
}

View File

@@ -21,12 +21,12 @@ go_library(
"//beacon-chain:__subpackages__",
"//fuzz:__pkg__",
"//shared/testutil:__pkg__",
"//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/stateutil:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
@@ -50,6 +50,7 @@ go_test(
name = "go_default_test",
size = "medium",
srcs = [
"attestation_regression_test.go",
"attestation_test.go",
"attester_slashing_test.go",
"block_operations_fuzz_test.go",
@@ -62,11 +63,12 @@ go_test(
"proposer_slashing_test.go",
"randao_test.go",
],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
shard_count = 2,
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/aggregation:go_default_library",
"//shared/aggregation/attestations:go_default_library",
@@ -82,7 +84,6 @@ go_test(
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

View File

@@ -12,6 +12,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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,10 +22,14 @@ import (
func ProcessAttestations(
ctx context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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")
}
var err error
for idx, attestation := range 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)
@@ -67,23 +72,27 @@ func ProcessAttestation(
beaconState *stateTrie.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
beaconState, err := ProcessAttestationNoVerify(ctx, beaconState, att)
beaconState, err := ProcessAttestationNoVerifySignature(ctx, beaconState, att)
if err != nil {
return nil, err
}
return beaconState, VerifyAttestation(ctx, beaconState, att)
return beaconState, VerifyAttestationSignature(ctx, beaconState, att)
}
// ProcessAttestationsNoVerify applies processing operations to a block's inner attestation
// ProcessAttestationsNoVerifySignature applies processing operations to a block's inner attestation
// records. The only difference would be that the attestation signature would not be verified.
func ProcessAttestationsNoVerify(
func ProcessAttestationsNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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
var err error
for idx, attestation := range body.Attestations {
beaconState, err = ProcessAttestationNoVerify(ctx, beaconState, attestation)
beaconState, err = ProcessAttestationNoVerifySignature(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
}
@@ -91,14 +100,14 @@ func ProcessAttestationsNoVerify(
return beaconState, nil
}
// ProcessAttestationNoVerify processes the attestation without verifying the attestation signature. This
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerify(
func ProcessAttestationNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerify")
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
defer span.End()
if att == nil || att.Data == nil || att.Data.Target == nil {
@@ -149,7 +158,7 @@ func ProcessAttestationNoVerify(
return nil, err
}
c := helpers.SlotCommitteeCount(activeValidatorCount)
if att.Data.CommitteeIndex > c {
if att.Data.CommitteeIndex >= c {
return nil, fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
}
@@ -196,17 +205,28 @@ func ProcessAttestationNoVerify(
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
}
// VerifyAttestations will verify the signatures of the provided attestations. This method performs
// 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 VerifyAttestations(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestations")
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 {
@@ -234,7 +254,7 @@ func VerifyAttestations(ctx context.Context, beaconState *stateTrie.BeaconState,
if err != nil {
return err
}
if err := verifyAttestationsWithDomain(ctx, beaconState, preForkAtts, prevDomain); err != nil {
if err := verifyAttestationsSigWithDomain(ctx, beaconState, preForkAtts, prevDomain); err != nil {
return err
}
} else if len(preForkAtts) > 0 {
@@ -249,12 +269,12 @@ func VerifyAttestations(ctx context.Context, beaconState *stateTrie.BeaconState,
return err
}
return verifyAttestationsWithDomain(ctx, beaconState, postForkAtts, currDomain)
return verifyAttestationsSigWithDomain(ctx, beaconState, postForkAtts, currDomain)
}
// VerifyAttestation converts and attestation into an indexed attestation and verifies
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
// the signature in that attestation.
func VerifyAttestation(ctx context.Context, beaconState *stateTrie.BeaconState, att *ethpb.Attestation) error {
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)
}
@@ -294,7 +314,7 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.Beacon
return err
}
indices := indexedAtt.AttestingIndices
pubkeys := []bls.PublicKey{}
var pubkeys []bls.PublicKey
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
pk, err := bls.PublicKeyFromBytes(pubkeyAtIdx[:])
@@ -308,7 +328,7 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.Beacon
// Inner method to verify attestations. This abstraction allows for the domain to be provided as an
// argument.
func verifyAttestationsWithDomain(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) error {
func verifyAttestationsSigWithDomain(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) error {
if len(atts) == 0 {
return nil
}
@@ -316,7 +336,7 @@ func verifyAttestationsWithDomain(ctx context.Context, beaconState *stateTrie.Be
if err != nil {
return err
}
verify, err := bls.VerifyMultipleSignatures(set.Signatures, set.Messages, set.PublicKeys)
verify, err := set.Verify()
if err != nil {
return errors.Errorf("got error in multiple verification: %v", err)
}
@@ -325,3 +345,35 @@ func verifyAttestationsWithDomain(ctx context.Context, beaconState *stateTrie.Be
}
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

@@ -0,0 +1,44 @@
package blocks_test
import (
"context"
"io/ioutil"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
// Beaconfuzz discovered an off by one issue where an attestation could be produced which would pass
// validation when att.Data.CommitteeIndex is 1 and the committee count per slot is also 1. The only
// valid att.Data.Committee index would be 0, so this is an off by one error.
// See: https://github.com/sigp/beacon-fuzz/issues/78
func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
attData, err := ioutil.ReadFile("testdata/beaconfuzz_78_attestation.ssz")
if err != nil {
t.Fatal(err)
}
att := &ethpb.Attestation{}
if err := att.UnmarshalSSZ(attData); err != nil {
t.Fatal(err)
}
stateData, err := ioutil.ReadFile("testdata/beaconfuzz_78_beacon.ssz")
if err != nil {
t.Fatal(err)
}
spb := &pb.BeaconState{}
if err := spb.UnmarshalSSZ(stateData); err != nil {
t.Fatal(err)
}
st, err := state.InitializeFromProtoUnsafe(spb)
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
_, err = blocks.ProcessAttestationNoVerifySignature(ctx, st, att)
require.ErrorContains(t, "committee index 1 >= committee count 1", err)
}

View File

@@ -15,6 +15,7 @@ import (
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"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"
@@ -25,12 +26,13 @@ func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Slot: 5,
},
},
}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
@@ -43,7 +45,7 @@ func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
params.BeaconConfig().MinAttestationInclusionDelay,
beaconState.Slot(),
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -53,7 +55,8 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0}}}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{att},
},
@@ -72,7 +75,7 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
helpers.PrevEpoch(beaconState),
helpers.CurrentEpoch(beaconState),
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -81,13 +84,14 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 1},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
},
}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
@@ -104,18 +108,18 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
helpers.CurrentEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
block.Body.Attestations[0].Data.Source.Root = []byte{}
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, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -127,14 +131,15 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
Target: &ethpb.Checkpoint{Epoch: 1},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Slot: params.BeaconConfig().SlotsPerEpoch,
},
AggregationBits: aggBits,
},
}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
@@ -152,19 +157,19 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
helpers.PrevEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
block.Body.Attestations[0].Data.Target.Epoch = helpers.CurrentEpoch(beaconState)
block.Body.Attestations[0].Data.Source.Root = []byte{}
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.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, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -179,7 +184,8 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
AggregationBits: aggBits,
}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{att},
},
@@ -194,7 +200,7 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, expected, err)
}
@@ -207,10 +213,12 @@ func TestProcessAttestations_OK(t *testing.T) {
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
},
AggregationBits: aggBits,
Signature: make([]byte, 96),
}
cfc := beaconState.CurrentJustifiedCheckpoint()
@@ -230,25 +238,23 @@ func TestProcessAttestations_OK(t *testing.T) {
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
att.Signature = bls.AggregateSignatures(sigs).Marshal()
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{att},
},
}
block := testutil.NewBeaconBlock()
block.Block.Body.Attestations = []*ethpb.Attestation{att}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, 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: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
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)
aggBits1.SetBitAt(0, true)
@@ -260,7 +266,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
}
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
cfc.Root = bytesutil.PadTo([]byte("hello-world"), 32)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
@@ -276,7 +282,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
require.NoError(t, err)
sigs[i] = sig
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
aggBits2 := bitfield.NewBitlist(4)
aggBits2.SetBitAt(1, true)
@@ -299,7 +305,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
require.NoError(t, err)
sigs[i] = sig
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
_, err = attaggregation.AggregatePair(att1, att2)
assert.ErrorContains(t, aggregation.ErrBitsOverlap.Error(), err)
@@ -311,8 +317,9 @@ 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[:]},
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
}
aggBits1 := bitfield.NewBitlist(9)
aggBits1.SetBitAt(0, true)
@@ -320,6 +327,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
att1 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits1,
Signature: make([]byte, 32),
}
cfc := beaconState.CurrentJustifiedCheckpoint()
@@ -339,7 +347,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
require.NoError(t, err)
sigs[i] = sig
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
aggBits2 := bitfield.NewBitlist(9)
aggBits2.SetBitAt(2, true)
@@ -347,6 +355,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
att2 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits2,
Signature: make([]byte, 32),
}
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
@@ -361,20 +370,17 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
require.NoError(t, err)
sigs[i] = sig
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()[:]
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
aggregatedAtt, err := attaggregation.AggregatePair(att1, att2)
require.NoError(t, err)
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{aggregatedAtt},
},
}
block := testutil.NewBeaconBlock()
block.Block.Body.Attestations = []*ethpb.Attestation{aggregatedAtt}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
assert.NoError(t, err)
}
@@ -384,11 +390,11 @@ func TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch(t *testing.T) {
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Slot: params.BeaconConfig().SlotsPerEpoch,
Target: &ethpb.Checkpoint{},
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.ProcessAttestationNoVerify(context.TODO(), beaconState, att)
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.ErrorContains(t, wanted, err)
}
@@ -404,7 +410,7 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
@@ -419,7 +425,7 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err = blocks.ProcessAttestationNoVerify(context.TODO(), beaconState, att)
_, err = blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
@@ -433,7 +439,7 @@ func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
Data: &ethpb.AttestationData{
CommitteeIndex: 100,
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
@@ -444,7 +450,7 @@ func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err := blocks.ProcessAttestationNoVerify(context.TODO(), beaconState, att)
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.ErrorContains(t, "committee index 100 >= committee count 1", err)
}
@@ -486,8 +492,8 @@ func TestConvertToIndexed_OK(t *testing.T) {
attestation := &ethpb.Attestation{
Signature: sig[:],
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
}
for _, tt := range tests {
@@ -512,8 +518,9 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
@@ -535,33 +542,57 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: 2,
Root: make([]byte, 32),
},
Source: &ethpb.Checkpoint{
Root: make([]byte, 32),
},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: []uint64{1},
Signature: make([]byte, 96),
}},
{attestation: &ethpb.IndexedAttestation{
Data: &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{
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{
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),
}},
}
@@ -608,7 +639,7 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
sig := keys[0].Sign([]byte{'t', 'e', 's', 't'})
list := bitfield.Bitlist{0b11111111}
atts := []*ethpb.Attestation{}
var atts []*ethpb.Attestation
for i := uint64(0); i < 1000; i++ {
atts = append(atts, &ethpb.Attestation{
Data: &ethpb.AttestationData{
@@ -653,32 +684,28 @@ func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
Fork: &pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
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,
Target: new(ethpb.Checkpoint),
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: nil,
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
@@ -696,11 +723,13 @@ func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
Target: new(ethpb.Checkpoint),
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: nil,
Signature: make([]byte, 96),
}
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
@@ -711,7 +740,9 @@ func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
require.NoError(t, blocks.VerifyAttestations(ctx, st, []*ethpb.Attestation{att1, att2}))
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) {
@@ -723,32 +754,33 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 35,
Validators: validators,
Fork: &pb.Fork{
Epoch: 1,
CurrentVersion: []byte{0, 1, 2, 3},
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
st := testutil.NewBeaconState()
require.NoError(t, st.SetSlot(35))
require.NoError(t, st.SetValidators(validators))
require.NoError(t, st.SetFork(&pb.Fork{
Epoch: 1,
CurrentVersion: []byte{0, 1, 2, 3},
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
}))
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,
Target: new(ethpb.Checkpoint),
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: nil,
Signature: make([]byte, 96),
}
prevDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch-1, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
@@ -766,13 +798,16 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1*params.BeaconConfig().SlotsPerEpoch + 1,
CommitteeIndex: 1,
Target: new(ethpb.Checkpoint),
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)},
},
Signature: nil,
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)
require.NoError(t, err)
sigs = nil
@@ -782,7 +817,9 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
require.NoError(t, blocks.VerifyAttestations(ctx, st, []*ethpb.Attestation{att1, att2}))
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) {
@@ -793,32 +830,28 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
Fork: &pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
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,
Target: new(ethpb.Checkpoint),
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: nil,
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
@@ -836,11 +869,13 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
Target: new(ethpb.Checkpoint),
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: nil,
Signature: make([]byte, 96),
}
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)

View File

@@ -35,8 +35,13 @@ import (
func ProcessAttesterSlashings(
ctx context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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 {
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, errors.Wrapf(err, "could not verify attester slashing %d", idx)
@@ -110,7 +115,7 @@ func VerifyAttesterSlashing(ctx context.Context, beaconState *stateTrie.BeaconSt
// # Surround vote
// (data_1.source.epoch < data_2.source.epoch and data_2.target.epoch < data_1.target.epoch)
// )
func IsSlashableAttestationData(data1 *ethpb.AttestationData, data2 *ethpb.AttestationData) bool {
func IsSlashableAttestationData(data1, data2 *ethpb.AttestationData) bool {
if data1 == nil || data2 == nil || data1.Target == nil || data2.Target == nil || data1.Source == nil || data2.Source == nil {
return false
}

View File

@@ -2,7 +2,6 @@ package blocks_test
import (
"context"
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
@@ -11,6 +10,7 @@ import (
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
@@ -19,12 +19,14 @@ import (
func TestSlashableAttestationData_CanSlash(t *testing.T) {
att1 := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1},
Source: &ethpb.Checkpoint{Root: []byte{'A'}},
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},
Source: &ethpb.Checkpoint{Root: []byte{'B'}},
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'B'}, 32)},
BeaconBlockRoot: make([]byte, 32),
}
assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable")
att1.Target.Epoch = 4
@@ -38,19 +40,23 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
{
Attestation_1: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0},
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},
Target: &ethpb.Checkpoint{Epoch: 1},
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),
},
},
}
registry := []*ethpb.Validator{}
var registry []*ethpb.Validator
currentSlot := uint64(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
@@ -58,18 +64,18 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
Slot: currentSlot,
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: slashings,
},
}
want := fmt.Sprint("attestations are not slashable")
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, block.Body)
assert.ErrorContains(t, want, err)
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, "attestations are not slashable", err)
}
func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T) {
registry := []*ethpb.Validator{}
var registry []*ethpb.Validator
currentSlot := uint64(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
@@ -82,30 +88,34 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
{
Attestation_1: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
Attestation_2: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
},
}
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: slashings,
},
}
want := fmt.Sprint("validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE")
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, block.Body)
assert.ErrorContains(t, want, err)
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE", err)
}
func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
@@ -116,8 +126,9 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
att1 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: []uint64{0, 1},
}
@@ -128,12 +139,13 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
sig0 := privKeys[0].Sign(signingRoot[:])
sig1 := privKeys[1].Sign(signingRoot[:])
aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1})
att1.Signature = aggregateSig.Marshal()[:]
att1.Signature = aggregateSig.Marshal()
att2 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0},
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: []uint64{0, 1},
}
@@ -142,7 +154,7 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
sig0 = privKeys[0].Sign(signingRoot[:])
sig1 = privKeys[1].Sign(signingRoot[:])
aggregateSig = bls.AggregateSignatures([]bls.Signature{sig0, sig1})
att2.Signature = aggregateSig.Marshal()[:]
att2.Signature = aggregateSig.Marshal()
slashings := []*ethpb.AttesterSlashing{
{
@@ -154,13 +166,14 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
currentSlot := 2 * params.BeaconConfig().SlotsPerEpoch
require.NoError(t, beaconState.SetSlot(currentSlot))
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: slashings,
},
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, block.Body)
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
require.NoError(t, err)
newRegistry := newState.Validators()

View File

@@ -9,51 +9,50 @@ import (
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
//"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
ethereum_beacon_p2p_v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestFuzzProcessAttestationNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
ctx := context.Background()
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
att := &eth.Attestation{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(att)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
_, err = ProcessAttestationNoVerify(ctx, s, att)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessAttestationNoVerifySignature(ctx, s, att)
_ = err
}
}
func TestFuzzProcessBlockHeader_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
block := &eth.SignedBeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
_, err = ProcessBlockHeader(s, block)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeader(context.Background(), s, block)
_ = err
}
}
func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
ba := []byte{}
var ba []byte
pubkey := [48]byte{}
sig := [96]byte{}
domain := [4]byte{}
p := []byte{}
s := []byte{}
d := []byte{}
var p []byte
var s []byte
var d []byte
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(&ba)
fuzzer.Fuzz(&pubkey)
@@ -63,6 +62,7 @@ func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
fuzzer.Fuzz(&s)
fuzzer.Fuzz(&d)
err := verifySignature(ba, pubkey[:], sig[:], domain[:])
_ = err
err = verifySignature(ba, p, s, d)
_ = err
}
@@ -70,14 +70,14 @@ func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
func TestFuzzProcessEth1DataInBlock_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
block := &eth.BeaconBlock{}
b := &eth.SignedBeaconBlock{}
state := &stateTrie.BeaconState{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := ProcessEth1DataInBlock(state, block)
fuzzer.Fuzz(b)
s, err := ProcessEth1DataInBlock(context.Background(), state, b)
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, block)
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and block: %v", s, err, state, b)
}
}
}
@@ -98,13 +98,14 @@ func TestFuzzareEth1DataEqual_10000(t *testing.T) {
func TestFuzzEth1DataHasEnoughSupport_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
eth1data := &eth.Eth1Data{}
stateVotes := []*eth.Eth1Data{}
var stateVotes []*eth.Eth1Data
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(eth1data)
fuzzer.Fuzz(&stateVotes)
s, err := beaconstate.InitializeFromProto(&ethereum_beacon_p2p_v1.BeaconState{
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: stateVotes,
})
require.NoError(t, err)
_, err = Eth1DataHasEnoughSupport(s, eth1data)
_ = err
}
@@ -113,13 +114,14 @@ func TestFuzzEth1DataHasEnoughSupport_10000(t *testing.T) {
func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
block := &eth.BeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeaderNoVerify(s, block)
_ = err
}
@@ -127,29 +129,31 @@ func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
func TestFuzzProcessRandao_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessRandao(s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandao(context.Background(), s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandaoNoVerify(s, blockBody)
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)
@@ -159,28 +163,30 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
func TestFuzzProcessProposerSlashings_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessProposerSlashings(ctx, s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessProposerSlashings(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
proposerSlashing := &eth.ProposerSlashing{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(proposerSlashing)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyProposerSlashing(s, proposerSlashing)
_ = err
}
@@ -188,29 +194,31 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
func TestFuzzProcessAttesterSlashings_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttesterSlashings(ctx, s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttesterSlashings(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzVerifyAttesterSlashing_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
attesterSlashing := &eth.AttesterSlashing{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attesterSlashing)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttesterSlashing(ctx, s, attesterSlashing)
_ = err
}
@@ -240,45 +248,48 @@ func TestFuzzslashableAttesterIndices_10000(t *testing.T) {
func TestFuzzProcessAttestations_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttestations(ctx, s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestations(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttestationsNoVerify(ctx, s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzProcessAttestation_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
attestation := &eth.Attestation{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestation(ctx, s, attestation)
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, attestation)
@@ -288,13 +299,14 @@ func TestFuzzProcessAttestation_10000(t *testing.T) {
func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
idxAttestation := &eth.IndexedAttestation{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(idxAttestation)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyIndexedAttestation(ctx, s, idxAttestation)
_ = err
}
@@ -302,44 +314,47 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
func TestFuzzVerifyAttestation_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
attestation := &eth.Attestation{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
err = VerifyAttestation(ctx, s, attestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
}
}
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessDeposits(ctx, s, blockBody.Deposits)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposits(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzProcessPreGenesisDeposit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
deposit := &eth.Deposit{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessPreGenesisDeposits(ctx, s, []*eth.Deposit{deposit})
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, deposit)
@@ -349,13 +364,14 @@ func TestFuzzProcessPreGenesisDeposit_10000(t *testing.T) {
func TestFuzzProcessDeposit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
deposit := &eth.Deposit{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposit(s, deposit, true)
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, deposit)
@@ -365,12 +381,13 @@ func TestFuzzProcessDeposit_10000(t *testing.T) {
func TestFuzzverifyDeposit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
state := &pb.BeaconState{}
deposit := &eth.Deposit{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = verifyDeposit(s, deposit)
_ = err
}
@@ -378,31 +395,33 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessVoluntaryExits(ctx, s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(ctx, s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessVoluntaryExitsNoVerify(s, blockBody)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(context.Background(), s, 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, blockBody)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
}
}
@@ -410,7 +429,7 @@ func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
func TestFuzzVerifyExit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
ve := &eth.SignedVoluntaryExit{}
val := &beaconstate.ReadOnlyValidator{}
val := &stateTrie.ReadOnlyValidator{}
fork := &pb.Fork{}
var slot uint64
@@ -419,7 +438,7 @@ func TestFuzzVerifyExit_10000(t *testing.T) {
fuzzer.Fuzz(val)
fuzzer.Fuzz(fork)
fuzzer.Fuzz(&slot)
err := VerifyExit(val, slot, fork, ve, params.BeaconConfig().ZeroHash[:])
err := VerifyExitAndSignature(val, slot, fork, ve, params.BeaconConfig().ZeroHash[:])
_ = err
}
}

View File

@@ -39,30 +39,34 @@ 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},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root1[:]},
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root1[:]},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: setA,
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
require.NoError(t, err)
signingRoot, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err, "Could not get signing root of beacon block header")
aggSigs := []bls.Signature{}
var aggSigs []bls.Signature
for _, index := range setA {
sig := privKeys[index].Sign(signingRoot[:])
aggSigs = append(aggSigs, sig)
}
aggregateSig := bls.AggregateSignatures(aggSigs)
att1.Signature = aggregateSig.Marshal()[:]
att1.Signature = aggregateSig.Marshal()
root2 := [32]byte{'d', 'o', 'u', 'b', 'l', 'e', '2'}
att2 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root2[:]},
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: root2[:]},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: setB,
Signature: make([]byte, 96),
}
signingRoot, err = helpers.ComputeSigningRoot(att2.Data, domain)
assert.NoError(t, err, "Could not get signing root of beacon block header")
@@ -72,7 +76,7 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
aggSigs = append(aggSigs, sig)
}
aggregateSig = bls.AggregateSignatures(aggSigs)
att2.Signature = aggregateSig.Marshal()[:]
att2.Signature = aggregateSig.Marshal()
slashings := []*ethpb.AttesterSlashing{
{
@@ -84,13 +88,14 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
currentSlot := 2 * params.BeaconConfig().SlotsPerEpoch
require.NoError(t, beaconState.SetSlot(currentSlot))
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: slashings,
},
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, block.Body)
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
require.NoError(t, err)
newRegistry := newState.Validators()
if !newRegistry[expectedSlashedVal].Slashed {

View File

@@ -25,7 +25,8 @@ func ProcessPreGenesisDeposits(
deposits []*ethpb.Deposit,
) (*stateTrie.BeaconState, error) {
var err error
beaconState, err = ProcessDeposits(ctx, beaconState, deposits)
beaconState, err = ProcessDeposits(ctx, beaconState, &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{Deposits: deposits}}})
if err != nil {
return nil, errors.Wrap(err, "could not process deposit")
}
@@ -66,10 +67,14 @@ func ProcessPreGenesisDeposits(
func ProcessDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
deposits []*ethpb.Deposit,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
var err 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
@@ -153,8 +158,7 @@ func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit,
if err != nil {
return nil, err
}
depositSig := deposit.Data.Signature
if err := verifyDepositDataSigningRoot(deposit.Data, pubKey, depositSig, domain); err != nil {
if err := verifyDepositDataSigningRoot(deposit.Data, domain); err != nil {
// Ignore this error as in the spec pseudo code.
log.Debugf("Skipping deposit: could not verify deposit data signature: %v", err)
return beaconState, nil
@@ -197,7 +201,7 @@ func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) e
}
receiptRoot := eth1Data.DepositRoot
leaf, err := ssz.HashTreeRoot(deposit.Data)
leaf, err := deposit.Data.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not tree hash deposit data")
}
@@ -206,17 +210,19 @@ func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) e
leaf[:],
int(beaconState.Eth1DepositIndex()),
deposit.Proof,
params.BeaconConfig().DepositContractTreeDepth,
); !ok {
return fmt.Errorf(
"deposit merkle branch of deposit root did not verify for root: %#x",
receiptRoot,
)
}
return nil
}
// Deprecated: This method uses deprecated ssz.SigningRoot.
func verifyDepositDataSigningRoot(obj *ethpb.Deposit_Data, pub []byte, signature []byte, domain []byte) error {
func verifyDepositDataSigningRoot(obj *ethpb.Deposit_Data, domain []byte) error {
return depositutil.VerifyDepositSignature(obj, domain)
}
@@ -225,7 +231,7 @@ func verifyDepositDataWithDomain(ctx context.Context, deps []*ethpb.Deposit, dom
return nil
}
pks := make([]bls.PublicKey, len(deps))
sigs := make([]bls.Signature, len(deps))
sigs := make([][]byte, len(deps))
msgs := make([][32]byte, len(deps))
for i, dep := range deps {
if ctx.Err() != nil {
@@ -234,17 +240,12 @@ func verifyDepositDataWithDomain(ctx context.Context, deps []*ethpb.Deposit, dom
if dep == nil || dep.Data == nil {
return errors.New("nil deposit")
}
dpk, err := bls.PublicKeyFromBytes(dep.Data.PublicKey)
if err != nil {
return err
}
pks[i] = dpk
dsig, err := bls.SignatureFromBytes(dep.Data.Signature)
if err != nil {
return err
}
sigs[i] = dsig
sigs[i] = dep.Data.Signature
root, err := ssz.SigningRoot(dep.Data)
if err != nil {
return errors.Wrap(err, "could not get signing root")
@@ -253,7 +254,7 @@ func verifyDepositDataWithDomain(ctx context.Context, deps []*ethpb.Deposit, dom
ObjectRoot: root[:],
Domain: domain,
}
ctrRoot, err := ssz.HashTreeRoot(signingData)
ctrRoot, err := signingData.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get container root")
}

View File

@@ -5,7 +5,6 @@ import (
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
@@ -26,7 +25,8 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
// 3 deposits from the same validator
Deposits: []*ethpb.Deposit{dep[0], dep[1], dep[2]},
@@ -49,7 +49,7 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, block.Body.Deposits)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
require.NoError(t, err, "Expected block deposits to process correctly")
assert.Equal(t, 2, len(newState.Validators()), "Incorrect validator count")
@@ -58,21 +58,23 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
deposit := &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte{1, 2, 3},
Signature: make([]byte, 96),
PublicKey: bytesutil.PadTo([]byte{1, 2, 3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
}
leaf, err := ssz.HashTreeRoot(deposit.Data)
leaf, err := deposit.Data.HashTreeRoot()
require.NoError(t, err)
// We then create a merkle branch for the test.
depositTrie, err := trieutil.GenerateTrieFromItems([][]byte{leaf[:]}, int(params.BeaconConfig().DepositContractTreeDepth))
depositTrie, err := trieutil.GenerateTrieFromItems([][]byte{leaf[:]}, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate trie")
proof, err := depositTrie.MerkleProof(0)
require.NoError(t, err, "Could not generate proof")
deposit.Proof = proof
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{deposit},
},
@@ -85,7 +87,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
})
require.NoError(t, err)
want := "deposit root did not verify"
_, err = blocks.ProcessDeposits(context.Background(), beaconState, block.Body.Deposits)
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -95,7 +97,8 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{dep[0]},
},
@@ -117,7 +120,7 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, block.Body.Deposits)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
require.NoError(t, err, "Expected block deposits to process correctly")
if newState.Balances()[1] != dep[0].Data.Amount {
t.Errorf(
@@ -129,28 +132,32 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
}
func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T) {
sk := bls.RandKey()
sk, err := bls.RandKey()
require.NoError(t, err)
deposit := &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: sk.PublicKey().Marshal(),
Amount: 1000,
PublicKey: sk.PublicKey().Marshal(),
Amount: 1000,
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
}
sr, err := helpers.ComputeSigningRoot(deposit.Data, bytesutil.ToBytes(3, 8))
sr, err := helpers.ComputeSigningRoot(deposit.Data, bytesutil.ToBytes(3, 32))
require.NoError(t, err)
sig := sk.Sign(sr[:])
deposit.Data.Signature = sig.Marshal()
leaf, err := ssz.HashTreeRoot(deposit.Data)
leaf, err := deposit.Data.HashTreeRoot()
require.NoError(t, err)
// We then create a merkle branch for the test.
depositTrie, err := trieutil.GenerateTrieFromItems([][]byte{leaf[:]}, int(params.BeaconConfig().DepositContractTreeDepth))
depositTrie, err := trieutil.GenerateTrieFromItems([][]byte{leaf[:]}, params.BeaconConfig().DepositContractTreeDepth)
require.NoError(t, err, "Could not generate trie")
proof, err := depositTrie.MerkleProof(0)
require.NoError(t, err, "Could not generate proof")
deposit.Proof = proof
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{deposit},
},
@@ -175,7 +182,7 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, block.Body.Deposits)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
require.NoError(t, err, "Process deposit failed")
assert.Equal(t, uint64(1000+50), newState.Balances()[1], "Expected balance at index 1 to be 1050")
}

View File

@@ -2,6 +2,7 @@ package blocks
import (
"bytes"
"context"
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
@@ -18,7 +19,8 @@ import (
// 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(beaconState *stateTrie.BeaconState, block *ethpb.BeaconBlock) (*stateTrie.BeaconState, error) {
func ProcessEth1DataInBlock(_ context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) (*stateTrie.BeaconState, error) {
block := b.Block
if beaconState == nil {
return nil, errors.New("nil state")
}

View File

@@ -1,6 +1,7 @@
package blocks_test
import (
"context"
"fmt"
"testing"
@@ -9,7 +10,9 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
)
@@ -19,7 +22,7 @@ func FakeDeposits(n uint64) []*ethpb.Eth1Data {
for i := uint64(0); i < n; i++ {
deposits[i] = &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: []byte("root"),
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
}
}
return deposits
@@ -36,7 +39,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: []byte("root"),
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
hasSupport: true,
votingPeriodLength: 7,
@@ -44,7 +47,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: []byte("root"),
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
hasSupport: false,
votingPeriodLength: 8,
@@ -52,7 +55,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: []byte("root"),
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
hasSupport: false,
votingPeriodLength: 10,
@@ -161,7 +164,8 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{2},
@@ -172,7 +176,7 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
period := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
for i := uint64(0); i < period; i++ {
beaconState, err = blocks.ProcessEth1DataInBlock(beaconState, block)
beaconState, err = blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
require.NoError(t, err)
}
@@ -180,10 +184,10 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), beaconstate.CopyETH1Data(block.Body.Eth1Data)) {
if !proto.Equal(beaconState.Eth1Data(), beaconstate.CopyETH1Data(b.Block.Body.Eth1Data)) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
block.Body.Eth1Data,
b.Block.Body.Eth1Data,
beaconState.Eth1Data(),
)
}

View File

@@ -13,6 +13,13 @@ import (
"github.com/prysmaticlabs/prysm/shared/params"
)
// ValidatorAlreadyExitedMsg defines a message saying that a validator has already exited.
var ValidatorAlreadyExitedMsg = "validator has already submitted an exit, which will take place at epoch"
// ValidatorCannotExitYetMsg defines a message saying that a validator cannot exit
// because it has not been active long enough.
var ValidatorCannotExitYetMsg = "validator has not been active long enough to exit"
// ProcessVoluntaryExits is one of the operations performed
// on each processed beacon block to determine which validators
// should exit the state's validator registry.
@@ -37,10 +44,15 @@ import (
// # Initiate exit
// initiate_validator_exit(state, exit.validator_index)
func ProcessVoluntaryExits(
ctx context.Context,
_ context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
@@ -50,7 +62,7 @@ func ProcessVoluntaryExits(
if err != nil {
return nil, err
}
if err := VerifyExit(val, beaconState.Slot(), beaconState.Fork(), exit, beaconState.GenesisValidatorRoot()); err != nil {
if err := VerifyExitAndSignature(val, beaconState.Slot(), beaconState.Fork(), exit, beaconState.GenesisValidatorRoot()); err != nil {
return nil, errors.Wrapf(err, "could not verify exit %d", idx)
}
beaconState, err = v.InitiateValidatorExit(beaconState, exit.Exit.ValidatorIndex)
@@ -61,9 +73,10 @@ func ProcessVoluntaryExits(
return beaconState, nil
}
// ProcessVoluntaryExitsNoVerify processes all the voluntary exits in
// ProcessVoluntaryExitsNoVerifySignature processes all the voluntary exits in
// a block body, without verifying their BLS signatures.
func ProcessVoluntaryExitsNoVerify(
// This function is here to satisfy fuzz tests.
func ProcessVoluntaryExitsNoVerifySignature(
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
@@ -93,7 +106,7 @@ func ProcessVoluntaryExitsNoVerify(
return beaconState, nil
}
// VerifyExit implements the spec defined validation for voluntary exits.
// VerifyExitAndSignature implements the spec defined validation for voluntary exits.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
@@ -112,7 +125,7 @@ func ProcessVoluntaryExitsNoVerify(
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
func VerifyExit(validator *stateTrie.ReadOnlyValidator, currentSlot uint64, fork *pb.Fork, signed *ethpb.SignedVoluntaryExit, genesisRoot []byte) error {
func VerifyExitAndSignature(validator *stateTrie.ReadOnlyValidator, currentSlot uint64, fork *pb.Fork, signed *ethpb.SignedVoluntaryExit, genesisRoot []byte) error {
if signed == nil || signed.Exit == nil {
return errors.New("nil exit")
}
@@ -154,9 +167,9 @@ func verifyExitConditions(validator *stateTrie.ReadOnlyValidator, currentSlot ui
if !helpers.IsActiveValidatorUsingTrie(validator, currentEpoch) {
return errors.New("non-active validator cannot exit")
}
// Verify the validator has not yet exited.
// Verify the validator has not yet submitted an exit.
if validator.ExitEpoch() != params.BeaconConfig().FarFutureEpoch {
return fmt.Errorf("validator has already exited at epoch: %v", validator.ExitEpoch())
return fmt.Errorf("%s: %v", ValidatorAlreadyExitedMsg, validator.ExitEpoch())
}
// Exits must specify an epoch when they become valid; they are not valid before then.
if currentEpoch < exit.Epoch {
@@ -165,7 +178,8 @@ func verifyExitConditions(validator *stateTrie.ReadOnlyValidator, currentSlot ui
// Verify the validator has been active long enough.
if currentEpoch < validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod {
return fmt.Errorf(
"validator has not been active long enough to exit, wanted epoch %d >= %d",
"%s: %d epochs vs required %d epochs",
ValidatorCannotExitYetMsg,
currentEpoch,
validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod,
)

View File

@@ -11,6 +11,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"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"
)
@@ -32,18 +33,19 @@ func TestProcessVoluntaryExits_ValidatorNotActive(t *testing.T) {
Validators: registry,
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "non-active validator cannot exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, block.Body)
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerify(state, block.Body)
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
@@ -65,20 +67,20 @@ func TestProcessVoluntaryExits_InvalidExitEpoch(t *testing.T) {
Slot: 0,
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "expected current epoch >= exit epoch"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, block.Body)
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerify(state, block.Body)
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
@@ -100,14 +102,45 @@ func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
Slot: 10,
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "validator has not been active long enough to exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, block.Body)
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 10,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: 10,
},
}
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 := "validator has already submitted an exit, which will take place at epoch: 10"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
}
@@ -138,22 +171,25 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, err)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
val, err := state.ValidatorAtIndex(0)
require.NoError(t, err)
val.PublicKey = priv.PublicKey().Marshal()[:]
val.PublicKey = priv.PublicKey().Marshal()
require.NoError(t, state.UpdateValidatorAtIndex(0, val))
exits[0].Signature, err = helpers.ComputeDomainAndSign(state, helpers.CurrentEpoch(state), exits[0].Exit, params.BeaconConfig().DomainVoluntaryExit, priv)
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
stateCopy := state.Copy()
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, block.Body)
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b)
require.NoError(t, err, "Could not process exits")
newRegistry := newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch) {
@@ -162,12 +198,11 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
}
// Check conformance with NoVerify Exit Method.
newState, err = blocks.ProcessVoluntaryExitsNoVerify(stateCopy, block.Body)
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)
}
}

View File

@@ -4,19 +4,27 @@ package blocks
import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// NewGenesisBlock returns the canonical, genesis block for the beacon chain protocol.
func NewGenesisBlock(stateRoot []byte) *ethpb.SignedBeaconBlock {
zeroHash := params.BeaconConfig().ZeroHash[:]
genBlock := &ethpb.BeaconBlock{
ParentRoot: zeroHash,
StateRoot: stateRoot,
Body: &ethpb.BeaconBlockBody{},
}
return &ethpb.SignedBeaconBlock{
Block: genBlock,
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ParentRoot: zeroHash,
StateRoot: bytesutil.PadTo(stateRoot, 32),
Body: &ethpb.BeaconBlockBody{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
},
},
Signature: params.BeaconConfig().EmptySignature[:],
}
return block
}

View File

@@ -4,11 +4,12 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
)
func TestGenesisBlock_InitializedCorrectly(t *testing.T) {
stateHash := []byte{0}
stateHash := bytesutil.PadTo([]byte{0}, 32)
b1 := blocks.NewGenesisBlock(stateHash)
assert.NotNil(t, b1.Block.ParentRoot, "Genesis block missing ParentHash field")

View File

@@ -2,13 +2,13 @@ package blocks
import (
"bytes"
"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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -37,6 +37,7 @@ import (
// # 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) {
@@ -99,7 +100,7 @@ func ProcessBlockHeaderNoVerify(
if parentHeader.Slot >= block.Slot {
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", block.Slot, parentHeader.Slot)
}
parentRoot, err := stateutil.BlockHeaderRoot(parentHeader)
parentRoot, err := parentHeader.HashTreeRoot()
if err != nil {
return nil, err
}
@@ -118,7 +119,7 @@ func ProcessBlockHeaderNoVerify(
return nil, fmt.Errorf("proposer at index %d was previously slashed", idx)
}
bodyRoot, err := stateutil.BlockBodyRoot(block.Body)
bodyRoot, err := block.Body.HashTreeRoot()
if err != nil {
return nil, err
}

View File

@@ -1,23 +1,22 @@
package blocks_test
import (
"context"
"io/ioutil"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/sirupsen/logrus"
"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/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
)
func init() {
@@ -28,40 +27,36 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 10}, // Must be less than block.Slot
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
state := testutil.NewBeaconState()
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),
}))
latestBlockSignedRoot, err := stateutil.BlockHeaderRoot(state.LatestBlockHeader())
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: pID,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: latestBlockSignedRoot[:],
},
}
block := testutil.NewBeaconBlock()
block.Block.ProposerIndex = pID
block.Block.Slot = 10
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = latestBlockSignedRoot[:]
block.Signature, err = helpers.ComputeDomainAndSign(state, currentEpoch, block.Block, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
@@ -72,36 +67,36 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, 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}))
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.SetSlot(10))
lbhdr, err := stateutil.BlockHeaderRoot(beaconState.LatestBlockHeader())
lbhdr, err := beaconState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: proposerIdx,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: lbhdr[:],
},
}
block := testutil.NewBeaconBlock()
block.Block.ProposerIndex = proposerIdx
block.Block.Slot = 10
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = lbhdr[:]
block.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx+1])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(beaconState, block)
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, block)
want := "signature did not verify"
assert.ErrorContains(t, want, err)
}
@@ -110,28 +105,30 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 9},
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
state := testutil.NewBeaconState()
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),
}))
lbhsr, err := ssz.HashTreeRoot(state.LatestBlockHeader())
lbhsr, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[5896].PublicKey = priv.PublicKey().Marshal()
@@ -146,7 +143,7 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
Signature: blockSig,
}
_, err = blocks.ProcessBlockHeader(state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
want := "is different than block slot"
assert.ErrorContains(t, want, err)
}
@@ -155,43 +152,35 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 9},
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
state := testutil.NewBeaconState()
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
bh := state.LatestBlockHeader()
bh.Slot = 9
require.NoError(t, state.SetLatestBlockHeader(bh))
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[5896].PublicKey = priv.PublicKey().Marshal()
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: pID,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: []byte{'A'},
},
Signature: blockSig,
}
block := testutil.NewBeaconBlock()
block.Block.Slot = 10
block.Block.ProposerIndex = pID
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = bytesutil.PadTo([]byte{'A'}, 32)
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
want := "does not match"
assert.ErrorContains(t, want, err)
}
@@ -200,46 +189,38 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 9},
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
parentRoot, err := stateutil.BlockHeaderRoot(state.LatestBlockHeader())
state := testutil.NewBeaconState()
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(10))
bh := state.LatestBlockHeader()
bh.Slot = 9
require.NoError(t, state.SetLatestBlockHeader(bh))
parentRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[12683].PublicKey = priv.PublicKey().Marshal()
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: pID,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: parentRoot[:],
},
Signature: blockSig,
}
block := testutil.NewBeaconBlock()
block.Block.Slot = 10
block.Block.ProposerIndex = pID
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = parentRoot[:]
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
want := "was previously slashed"
assert.ErrorContains(t, want, err)
}
@@ -248,43 +229,40 @@ func TestProcessBlockHeader_OK(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 9},
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
state := testutil.NewBeaconState()
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),
}))
latestBlockSignedRoot, err := stateutil.BlockHeaderRoot(state.LatestBlockHeader())
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: pID,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: latestBlockSignedRoot[:],
},
}
block := testutil.NewBeaconBlock()
block.Block.ProposerIndex = pID
block.Block.Slot = 10
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = latestBlockSignedRoot[:]
block.Signature, err = helpers.ComputeDomainAndSign(state, currentEpoch, block.Block, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
bodyRoot, err := stateutil.BlockBodyRoot(block.Block.Body)
bodyRoot, err := block.Block.Body.HashTreeRoot()
require.NoError(t, err, "Failed to hash block bytes got")
proposerIdx, err := helpers.BeaconProposerIndex(state)
@@ -294,7 +272,7 @@ func TestProcessBlockHeader_OK(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
newState, err := blocks.ProcessBlockHeader(state, block)
newState, err := blocks.ProcessBlockHeader(context.Background(), state, block)
require.NoError(t, err, "Failed to process block header got")
var zeroHash [32]byte
nsh := newState.LatestBlockHeader()
@@ -312,40 +290,37 @@ func TestBlockSignatureSet_OK(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: validators,
Slot: 10,
LatestBlockHeader: &ethpb.BeaconBlockHeader{Slot: 9},
Fork: &pb.Fork{
PreviousVersion: []byte{0, 0, 0, 0},
CurrentVersion: []byte{0, 0, 0, 0},
},
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
state := testutil.NewBeaconState()
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),
}))
latestBlockSignedRoot, err := stateutil.BlockHeaderRoot(state.LatestBlockHeader())
latestBlockSignedRoot, err := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
priv, err := bls.RandKey()
require.NoError(t, err)
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
ProposerIndex: pID,
Slot: 10,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: latestBlockSignedRoot[:],
},
}
block := testutil.NewBeaconBlock()
block.Block.Slot = 10
block.Block.ProposerIndex = pID
block.Block.Body.RandaoReveal = bytesutil.PadTo([]byte{'A', 'B', 'C'}, 96)
block.Block.ParentRoot = latestBlockSignedRoot[:]
block.Signature, err = helpers.ComputeDomainAndSign(state, currentEpoch, block.Block, params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
proposerIdx, err := helpers.BeaconProposerIndex(state)

View File

@@ -36,10 +36,15 @@ import (
//
// slash_validator(state, proposer_slashing.proposer_index)
func ProcessProposerSlashings(
ctx context.Context,
_ context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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
var err error
for idx, slashing := range body.ProposerSlashings {
if slashing == nil {
@@ -74,14 +79,14 @@ func VerifyProposerSlashing(
if pIdx != slashing.Header_2.Header.ProposerIndex {
return fmt.Errorf("mismatched indices, received %d == %d", slashing.Header_1.Header.ProposerIndex, slashing.Header_2.Header.ProposerIndex)
}
if proto.Equal(slashing.Header_1, slashing.Header_2) {
if proto.Equal(slashing.Header_1.Header, slashing.Header_2.Header) {
return errors.New("expected slashing headers to differ")
}
proposer, err := beaconState.ValidatorAtIndexReadOnly(slashing.Header_1.Header.ProposerIndex)
if err != nil {
return err
}
if !helpers.IsSlashableValidatorUsingTrie(proposer, helpers.SlotToEpoch(beaconState.Slot())) {
if !helpers.IsSlashableValidatorUsingTrie(proposer, helpers.SlotToEpoch(hSlot)) {
return fmt.Errorf("validator with key %#x is not slashable", proposer.PublicKey())
}
headers := []*ethpb.SignedBeaconBlockHeader{slashing.Header_1, slashing.Header_2}

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -39,13 +40,14 @@ func TestProcessProposerSlashings_UnmatchedHeaderSlots(t *testing.T) {
}
require.NoError(t, beaconState.SetSlot(currentSlot))
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
want := "mismatched header slots"
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block.Body)
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -71,13 +73,14 @@ func TestProcessProposerSlashings_SameHeaders(t *testing.T) {
}
require.NoError(t, beaconState.SetSlot(currentSlot))
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
want := "expected slashing headers to differ"
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block.Body)
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -97,15 +100,17 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 0,
Slot: 0,
BodyRoot: []byte("foo"),
},
Signature: []byte("A"),
Signature: bytesutil.PadTo([]byte("A"), 96),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 0,
Slot: 0,
BodyRoot: []byte("bar"),
},
Signature: []byte("B"),
Signature: bytesutil.PadTo([]byte("B"), 96),
},
},
}
@@ -115,7 +120,8 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
Slot: currentSlot,
})
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
@@ -124,7 +130,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
"validator with key %#x is not slashable",
bytesutil.ToBytes48(beaconState.Validators()[0].PublicKey),
)
_, err = blocks.ProcessProposerSlashings(context.Background(), beaconState, block.Body)
_, err = blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -138,7 +144,9 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: proposerIdx,
Slot: 0,
StateRoot: []byte("A"),
ParentRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
StateRoot: bytesutil.PadTo([]byte("A"), 32),
},
}
var err error
@@ -149,7 +157,9 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: proposerIdx,
Slot: 0,
StateRoot: []byte("B"),
ParentRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
StateRoot: bytesutil.PadTo([]byte("B"), 32),
},
}
header2.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, header2.Header, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
@@ -162,13 +172,10 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
},
}
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
block := testutil.NewBeaconBlock()
block.Block.Body.ProposerSlashings = slashings
newState, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block.Body)
newState, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block)
require.NoError(t, err)
newStateVals := newState.Validators()
@@ -177,3 +184,132 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
newStateVals[1].ExitEpoch, beaconState.Validators()[1].ExitEpoch)
}
}
func TestVerifyProposerSlashing(t *testing.T) {
type args struct {
beaconState *stateTrie.BeaconState
slashing *ethpb.ProposerSlashing
}
beaconState, sks := testutil.DeterministicGenesisState(t, 2)
currentSlot := uint64(0)
require.NoError(t, beaconState.SetSlot(currentSlot))
rand1, err := bls.RandKey()
require.NoError(t, err)
sig1 := rand1.Sign([]byte("foo")).Marshal()
rand2, err := bls.RandKey()
require.NoError(t, err)
sig2 := rand2.Sign([]byte("bar")).Marshal()
tests := []struct {
name string
args args
wantErr string
}{
{
name: "same header, same slot as state",
args: args{
slashing: &ethpb.ProposerSlashing{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: currentSlot,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte{}, 32),
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: currentSlot,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte{}, 32),
},
},
},
beaconState: beaconState,
},
wantErr: "expected slashing headers to differ",
},
{ // Regression test for https://github.com/sigp/beacon-fuzz/issues/74
name: "same header, different signatures",
args: args{
slashing: &ethpb.ProposerSlashing{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 0,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte{}, 32),
},
Signature: sig1,
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 0,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte{}, 32),
},
Signature: sig2,
},
},
beaconState: beaconState,
},
wantErr: "expected slashing headers to differ",
},
{
name: "slashing in future epoch",
args: args{
slashing: &ethpb.ProposerSlashing{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 65,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte("foo"), 32),
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 65,
StateRoot: bytesutil.PadTo([]byte{}, 32),
BodyRoot: bytesutil.PadTo([]byte{}, 32),
ParentRoot: bytesutil.PadTo([]byte("bar"), 32),
},
},
},
beaconState: beaconState,
},
wantErr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
testutil.ResetCache()
sk := sks[tt.args.slashing.Header_1.Header.ProposerIndex]
d, err := helpers.Domain(tt.args.beaconState.Fork(), helpers.SlotToEpoch(tt.args.slashing.Header_1.Header.Slot), params.BeaconConfig().DomainBeaconProposer, tt.args.beaconState.GenesisValidatorRoot())
require.NoError(t, err)
if tt.args.slashing.Header_1.Signature == nil {
sr, err := helpers.ComputeSigningRoot(tt.args.slashing.Header_1.Header, d)
require.NoError(t, err)
tt.args.slashing.Header_1.Signature = sk.Sign(sr[:]).Marshal()
}
if tt.args.slashing.Header_2.Signature == nil {
sr, err := helpers.ComputeSigningRoot(tt.args.slashing.Header_2.Header, d)
require.NoError(t, err)
tt.args.slashing.Header_2.Signature = sk.Sign(sr[:]).Marshal()
}
if err := blocks.VerifyProposerSlashing(tt.args.beaconState, tt.args.slashing); (err != nil || tt.wantErr != "") && err.Error() != tt.wantErr {
t.Errorf("VerifyProposerSlashing() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@@ -1,6 +1,8 @@
package blocks
import (
"context"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
@@ -24,14 +26,20 @@ import (
// mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal))
// state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
func ProcessRandao(
_ context.Context,
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
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
buf, proposerPub, domain, err := randaoSigningData(beaconState)
if err != nil {
return nil, err
}
if err := verifySignature(buf, proposerPub[:], body.RandaoReveal, domain); err != nil {
if err := verifySignature(buf, proposerPub, body.RandaoReveal, domain); err != nil {
return nil, errors.Wrap(err, "could not verify block randao")
}

View File

@@ -2,11 +2,11 @@ package blocks_test
import (
"bytes"
"context"
"encoding/binary"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -26,18 +26,19 @@ func TestProcessRandao_IncorrectProposerFailsVerification(t *testing.T) {
binary.LittleEndian.PutUint64(buf, epoch)
domain, err := helpers.Domain(beaconState.Fork(), epoch, params.BeaconConfig().DomainRandao, beaconState.GenesisValidatorRoot())
require.NoError(t, err)
root, err := ssz.HashTreeRoot(&pb.SigningData{ObjectRoot: buf, Domain: domain})
root, err := (&pb.SigningData{ObjectRoot: buf, Domain: domain}).HashTreeRoot()
require.NoError(t, err)
// We make the previous validator's index sign the message instead of the proposer.
epochSignature := privKeys[proposerIdx-1].Sign(root[:])
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
RandaoReveal: epochSignature.Marshal(),
},
}
want := "block randao: signature did not verify"
_, err = blocks.ProcessRandao(beaconState, block.Body)
_, err = blocks.ProcessRandao(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -48,15 +49,17 @@ func TestProcessRandao_SignatureVerifiesAndUpdatesLatestStateMixes(t *testing.T)
epochSignature, err := testutil.RandaoReveal(beaconState, epoch, privKeys)
require.NoError(t, err)
block := &ethpb.BeaconBlock{
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
RandaoReveal: epochSignature,
},
}
newState, err := blocks.ProcessRandao(
context.Background(),
beaconState,
block.Body,
b,
)
require.NoError(t, err, "Unexpected error processing block randao")
currentEpoch := helpers.CurrentEpoch(beaconState)

View File

@@ -6,7 +6,6 @@ import (
"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"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -16,32 +15,28 @@ import (
)
// retrieves the signature set from the raw data, public key,signature and domain provided.
func retrieveSignatureSet(signedData []byte, pub []byte, signature []byte, domain []byte) (*bls.SignatureSet, error) {
func retrieveSignatureSet(signedData, pub, signature, domain []byte) (*bls.SignatureSet, error) {
publicKey, err := bls.PublicKeyFromBytes(pub)
if err != nil {
return nil, errors.Wrap(err, "could not convert bytes to public key")
}
sig, err := bls.SignatureFromBytes(signature)
if err != nil {
return nil, errors.Wrap(err, "could not convert bytes to signature")
}
signingData := &pb.SigningData{
ObjectRoot: signedData,
Domain: domain,
}
root, err := ssz.HashTreeRoot(signingData)
root, err := signingData.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash container")
}
return &bls.SignatureSet{
Signatures: []bls.Signature{sig},
Signatures: [][]byte{signature},
PublicKeys: []bls.PublicKey{publicKey},
Messages: [][32]byte{root},
}, nil
}
// verifies the signature from the raw data, public key and domain provided.
func verifySignature(signedData []byte, pub []byte, signature []byte, domain []byte) error {
func verifySignature(signedData, pub, signature, domain []byte) error {
set, err := retrieveSignatureSet(signedData, pub, signature, domain)
if err != nil {
return err
@@ -53,7 +48,11 @@ func verifySignature(signedData []byte, pub []byte, signature []byte, domain []b
sig := set.Signatures[0]
publicKey := set.PublicKeys[0]
root := set.Messages[0]
if !sig.Verify(publicKey, root[:]) {
rSig, err := bls.SignatureFromBytes(sig)
if err != nil {
return err
}
if !rSig.Verify(publicKey, root[:]) {
return helpers.ErrSigFailedToVerify
}
return nil
@@ -71,7 +70,7 @@ func VerifyBlockSignature(beaconState *stateTrie.BeaconState, block *ethpb.Signe
return err
}
proposerPubKey := proposer.PublicKey
return helpers.VerifyBlockSigningRoot(block.Block, proposerPubKey[:], block.Signature, domain)
return helpers.VerifyBlockSigningRoot(block.Block, proposerPubKey, block.Signature, domain)
}
// BlockSignatureSet retrieves the block signature set from the provided block and its corresponding state.
@@ -98,7 +97,7 @@ func RandaoSignatureSet(beaconState *stateTrie.BeaconState,
if err != nil {
return nil, nil, err
}
set, err := retrieveSignatureSet(buf, proposerPub[:], body.RandaoReveal, domain)
set, err := retrieveSignatureSet(buf, proposerPub, body.RandaoReveal, domain)
if err != nil {
return nil, nil, err
}
@@ -130,15 +129,11 @@ func createAttestationSignatureSet(ctx context.Context, beaconState *stateTrie.B
return nil, nil
}
sigs := make([]bls.Signature, len(atts))
sigs := make([][]byte, len(atts))
pks := make([]bls.PublicKey, len(atts))
msgs := make([][32]byte, len(atts))
for i, a := range atts {
sig, err := bls.SignatureFromBytes(a.Signature)
if err != nil {
return nil, err
}
sigs[i] = sig
sigs[i] = a.Signature
c, err := helpers.BeaconCommitteeFromState(beaconState, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return nil, err
@@ -148,20 +143,16 @@ func createAttestationSignatureSet(ctx context.Context, beaconState *stateTrie.B
return nil, err
}
indices := ia.AttestingIndices
var pk bls.PublicKey
pubkeys := make([][]byte, len(indices))
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
p, err := bls.PublicKeyFromBytes(pubkeyAtIdx[:])
if err != nil {
return nil, errors.Wrap(err, "could not deserialize validator public key")
}
if pk == nil {
pk = p
} else {
pk.Aggregate(p)
}
pubkeys[i] = pubkeyAtIdx[:]
}
pks[i] = pk
aggP, err := bls.AggregatePublicKeys(pubkeys)
if err != nil {
return nil, err
}
pks[i] = aggP
root, err := helpers.ComputeSigningRoot(ia.Data, domain)
if err != nil {

View File

@@ -41,8 +41,8 @@ func runBlockHeaderTest(t *testing.T, config string) {
postSSZExists := true
if err != nil && strings.Contains(err.Error(), "could not locate file") {
postSSZExists = false
} else if err != nil {
t.Fatal(err)
} else {
require.NoError(t, err)
}
// Spectest blocks are not signed, so we'll call NoVerify to skip sig verification.

View File

@@ -1,13 +1,11 @@
package spectest
import (
"context"
"path"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -26,9 +24,7 @@ func runDepositTest(t *testing.T, config string) {
require.NoError(t, deposit.UnmarshalSSZ(depositFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{Deposits: []*ethpb.Deposit{deposit}}
testutil.RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, state *state.BeaconState, body *ethpb.BeaconBlockBody) (*state.BeaconState, error) {
return blocks.ProcessDeposits(ctx, state, body.Deposits)
})
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessDeposits)
})
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -16,7 +16,6 @@ go_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_go_ssz//:go_default_library",
],
)
@@ -33,6 +32,7 @@ go_test(
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1: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",
"@com_github_gogo_protobuf//proto:go_default_library",

View File

@@ -10,7 +10,6 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
@@ -46,7 +45,7 @@ func (s sortableIndices) Less(i, j int) bool {
// def get_attesting_balance(state: BeaconState, attestations: List[PendingAttestation]) -> Gwei:
// return get_total_balance(state, get_unslashed_attesting_indices(state, attestations))
func AttestingBalance(state *stateTrie.BeaconState, atts []*pb.PendingAttestation) (uint64, error) {
indices, err := unslashedAttestingIndices(state, atts)
indices, err := UnslashedAttestingIndices(state, atts)
if err != nil {
return 0, errors.Wrap(err, "could not get attesting indices")
}
@@ -148,10 +147,11 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat
// def process_slashings(state: BeaconState) -> None:
// epoch = get_current_epoch(state)
// total_balance = get_total_active_balance(state)
// adjusted_total_slashing_balance = min(sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER, total_balance)
// for index, validator in enumerate(state.validators):
// if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
// increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow
// penalty_numerator = validator.effective_balance // increment * min(sum(state.slashings) * 3, total_balance)
// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
// penalty = penalty_numerator // total_balance * increment
// decrease_balance(state, ValidatorIndex(index), penalty)
func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, error) {
@@ -174,10 +174,10 @@ func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, err
// a callback is used here to apply the following actions to all validators
// below equally.
increment := params.BeaconConfig().EffectiveBalanceIncrement
minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplier, totalBalance)
err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, error) {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
minSlashing := mathutil.Min(totalSlashing*3, totalBalance)
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / totalBalance * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
@@ -311,7 +311,7 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
BlockRoots: state.BlockRoots(),
StateRoots: state.StateRoots(),
}
batchRoot, err := ssz.HashTreeRoot(historicalBatch)
batchRoot, err := historicalBatch.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash historical batch")
}
@@ -330,7 +330,7 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
return state, nil
}
// unslashedAttestingIndices returns all the attesting indices from a list of attestations,
// UnslashedAttestingIndices returns all the attesting indices from a list of attestations,
// it sorts the indices and filters out the slashed ones.
//
// Spec pseudocode definition:
@@ -340,7 +340,7 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
// for a in attestations:
// output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits))
// return set(filter(lambda index: not state.validators[index].slashed, output))
func unslashedAttestingIndices(state *stateTrie.BeaconState, atts []*pb.PendingAttestation) ([]uint64, error) {
func UnslashedAttestingIndices(state *stateTrie.BeaconState, atts []*pb.PendingAttestation) ([]uint64, error) {
var setIndices []uint64
seen := make(map[uint64]bool)

View File

@@ -18,5 +18,6 @@ func TestFuzzFinalUpdates_10000(t *testing.T) {
s, err := beaconstate.InitializeFromProtoUnsafe(base)
require.NoError(t, err)
_, err = ProcessFinalUpdates(s)
_ = err
}
}

View File

@@ -1,16 +1,17 @@
package epoch
package epoch_test
import (
"bytes"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"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"
)
@@ -20,8 +21,8 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
atts := make([]*pb.PendingAttestation, 2)
for i := 0; i < len(atts); i++ {
atts[i] = &pb.PendingAttestation{
Data: &ethpb.AttestationData{Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{Epoch: 0},
Data: &ethpb.AttestationData{Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF},
}
@@ -42,7 +43,7 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
indices, err := unslashedAttestingIndices(state, atts)
indices, err := epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices)-1; i++ {
if indices[i] >= indices[i+1] {
@@ -55,7 +56,7 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
validators = state.Validators()
validators[slashedValidator].Slashed = true
require.NoError(t, state.SetValidators(validators))
indices, err = unslashedAttestingIndices(state, atts)
indices, err = epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices); i++ {
assert.NotEqual(t, slashedValidator, indices[i], "Slashed validator %d is not filtered", slashedValidator)
@@ -67,7 +68,7 @@ func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) {
atts := make([]*pb.PendingAttestation, 5)
for i := 0; i < len(atts); i++ {
atts[i] = &pb.PendingAttestation{
Data: &ethpb.AttestationData{Source: &ethpb.Checkpoint{},
Data: &ethpb.AttestationData{Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0}},
AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF},
}
@@ -88,7 +89,7 @@ func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) {
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
indices, err := unslashedAttestingIndices(state, atts)
indices, err := epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices)-1; i++ {
@@ -105,8 +106,8 @@ func TestAttestingBalance_CorrectBalance(t *testing.T) {
for i := 0; i < len(atts); i++ {
atts[i] = &pb.PendingAttestation{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{},
Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: uint64(i),
},
AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -134,7 +135,7 @@ func TestAttestingBalance_CorrectBalance(t *testing.T) {
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
balance, err := AttestingBalance(state, atts)
balance, err := epoch.AttestingBalance(state, atts)
require.NoError(t, err)
wanted := 256 * params.BeaconConfig().MaxEffectiveBalance
assert.Equal(t, wanted, balance)
@@ -159,9 +160,9 @@ func TestBaseReward_AccurateRewards(t *testing.T) {
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
c, err := BaseReward(state, 0)
c, err := epoch.BaseReward(state, 0)
require.NoError(t, err)
assert.Equal(t, tt.c, c, "BaseReward(%d)", tt.a)
assert.Equal(t, tt.c, c, "epoch.BaseReward(%d)", tt.a)
}
}
@@ -174,7 +175,7 @@ func TestProcessSlashings_NotSlashed(t *testing.T) {
}
s, err := state.InitializeFromProto(base)
require.NoError(t, err)
newState, err := ProcessSlashings(s)
newState, err := epoch.ProcessSlashings(s)
require.NoError(t, err)
wanted := params.BeaconConfig().MaxEffectiveBalance
assert.Equal(t, wanted, newState.Balances()[0], "Unexpected slashed balance")
@@ -252,7 +253,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
original := proto.Clone(tt.state)
s, err := state.InitializeFromProto(tt.state)
require.NoError(t, err)
newState, err := ProcessSlashings(s)
newState, err := epoch.ProcessSlashings(s)
require.NoError(t, err)
assert.Equal(t, tt.want, newState.Balances()[0], "ProcessSlashings({%v}) = newState; newState.Balances[0] = %d", original, newState.Balances()[0])
})
@@ -260,7 +261,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
}
func TestProcessFinalUpdates_CanProcess(t *testing.T) {
s := buildState(params.BeaconConfig().SlotsPerHistoricalRoot-1, params.BeaconConfig().SlotsPerEpoch)
s := buildState(t, params.BeaconConfig().SlotsPerHistoricalRoot-1, params.BeaconConfig().SlotsPerEpoch)
ce := helpers.CurrentEpoch(s)
ne := ce + 1
require.NoError(t, s.SetEth1DataVotes([]*ethpb.Eth1Data{}))
@@ -275,7 +276,7 @@ func TestProcessFinalUpdates_CanProcess(t *testing.T) {
mixes := s.RandaoMixes()
mixes[ce] = []byte{'A'}
require.NoError(t, s.SetRandaoMixes(mixes))
newS, err := ProcessFinalUpdates(s)
newS, err := epoch.ProcessFinalUpdates(s)
require.NoError(t, err)
// Verify effective balance is correctly updated.
@@ -286,9 +287,9 @@ func TestProcessFinalUpdates_CanProcess(t *testing.T) {
assert.Equal(t, newS.Slashings()[ce], newS.Slashings()[ne], "Unexpected slashed balance")
// Verify randao is correctly updated in the right position.
if mix, err := newS.RandaoMixAtIndex(ne); err != nil || bytes.Equal(mix, params.BeaconConfig().ZeroHash[:]) {
t.Error("latest RANDAO still zero hashes")
}
mix, err := newS.RandaoMixAtIndex(ne)
assert.NoError(t, err)
assert.DeepNotEqual(t, params.BeaconConfig().ZeroHash[:], mix, "latest RANDAO still zero hashes")
// Verify historical root accumulator was appended.
assert.Equal(t, 1, len(newS.HistoricalRoots()), "Unexpected slashed balance")
@@ -306,11 +307,11 @@ func TestProcessRegistryUpdates_NoRotation(t *testing.T) {
params.BeaconConfig().MaxEffectiveBalance,
params.BeaconConfig().MaxEffectiveBalance,
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
newState, err := ProcessRegistryUpdates(state)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch, "Could not update registry %d", i)
@@ -320,7 +321,7 @@ func TestProcessRegistryUpdates_NoRotation(t *testing.T) {
func TestProcessRegistryUpdates_EligibleToActivate(t *testing.T) {
base := &pb.BeaconState{
Slot: 5 * params.BeaconConfig().SlotsPerEpoch,
FinalizedCheckpoint: &ethpb.Checkpoint{Epoch: 6},
FinalizedCheckpoint: &ethpb.Checkpoint{Epoch: 6, Root: make([]byte, 32)},
}
limit, err := helpers.ValidatorChurnLimit(0)
require.NoError(t, err)
@@ -332,8 +333,9 @@ func TestProcessRegistryUpdates_EligibleToActivate(t *testing.T) {
})
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
newState, err := ProcessRegistryUpdates(state)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
assert.Equal(t, currentEpoch+1, validator.ActivationEligibilityEpoch, "Could not update registry %d, unexpected activation eligibility epoch", i)
@@ -357,11 +359,11 @@ func TestProcessRegistryUpdates_ActivationCompletes(t *testing.T) {
{ExitEpoch: params.BeaconConfig().MaxSeedLookahead,
ActivationEpoch: 5 + params.BeaconConfig().MaxSeedLookahead + 1},
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
newState, err := ProcessRegistryUpdates(state)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch, "Could not update registry %d, unexpected exit slot", i)
@@ -381,11 +383,11 @@ func TestProcessRegistryUpdates_ValidatorsEjected(t *testing.T) {
EffectiveBalance: params.BeaconConfig().EjectionBalance - 1,
},
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
newState, err := ProcessRegistryUpdates(state)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead+1, validator.ExitEpoch, "Could not update registry %d, unexpected exit slot", i)
@@ -393,11 +395,11 @@ func TestProcessRegistryUpdates_ValidatorsEjected(t *testing.T) {
}
func TestProcessRegistryUpdates_CanExits(t *testing.T) {
epoch := uint64(5)
exitEpoch := helpers.ActivationExitEpoch(epoch)
e := uint64(5)
exitEpoch := helpers.ActivationExitEpoch(e)
minWithdrawalDelay := params.BeaconConfig().MinValidatorWithdrawabilityDelay
base := &pb.BeaconState{
Slot: epoch * params.BeaconConfig().SlotsPerEpoch,
Slot: e * params.BeaconConfig().SlotsPerEpoch,
Validators: []*ethpb.Validator{
{
ExitEpoch: exitEpoch,
@@ -406,18 +408,18 @@ func TestProcessRegistryUpdates_CanExits(t *testing.T) {
ExitEpoch: exitEpoch,
WithdrawableEpoch: exitEpoch + minWithdrawalDelay},
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
newState, err := ProcessRegistryUpdates(state)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
assert.Equal(t, exitEpoch, validator.ExitEpoch, "Could not update registry %d, unexpected exit slot", i)
}
}
func buildState(slot uint64, validatorCount uint64) *state.BeaconState {
func buildState(t testing.TB, slot, validatorCount uint64) *state.BeaconState {
validators := make([]*ethpb.Validator, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
@@ -443,19 +445,15 @@ func buildState(slot uint64, validatorCount uint64) *state.BeaconState {
for i := 0; i < len(latestRandaoMixes); i++ {
latestRandaoMixes[i] = params.BeaconConfig().ZeroHash[:]
}
s, err := state.InitializeFromProto(&pb.BeaconState{
Slot: slot,
Balances: validatorBalances,
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
BlockRoots: make([][]byte, params.BeaconConfig().SlotsPerEpoch*10),
FinalizedCheckpoint: &ethpb.Checkpoint{},
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{},
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{},
})
if err != nil {
panic(err)
s := testutil.NewBeaconState()
if err := s.SetSlot(slot); err != nil {
t.Error(err)
}
if err := s.SetBalances(validatorBalances); err != nil {
t.Error(err)
}
if err := s.SetValidators(validators); err != nil {
t.Error(err)
}
return s
}

View File

@@ -14,10 +14,6 @@ import (
"go.opencensus.io/trace"
)
// Balances stores balances such as prev/current total validator balances, attested balances and more.
// It's used for metrics reporting.
var Balances *Balance
// ProcessAttestations process the attestations in state and update individual validator's pre computes,
// it also tracks and updates epoch attesting balances.
func ProcessAttestations(
@@ -56,7 +52,6 @@ func ProcessAttestations(
}
pBal = UpdateBalance(vp, pBal)
Balances = pBal
return vp, pBal, nil
}

View File

@@ -178,8 +178,7 @@ func TestProcessAttestations(t *testing.T) {
for i := 0; i < len(pVals); i++ {
pVals[i] = &precompute.Validator{CurrentEpochEffectiveBalance: 100}
}
pBal := &precompute.Balance{}
pVals, pBal, err = precompute.ProcessAttestations(context.Background(), beaconState, pVals, pBal)
pVals, _, err = precompute.ProcessAttestations(context.Background(), beaconState, pVals, &precompute.Balance{})
require.NoError(t, err)
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)

View File

@@ -49,7 +49,11 @@ import (
// if all(bits[0:2]) and old_current_justified_checkpoint.epoch + 1 == current_epoch:
// state.finalized_checkpoint = old_current_justified_checkpoint
func ProcessJustificationAndFinalizationPreCompute(state *stateTrie.BeaconState, pBal *Balance) (*stateTrie.BeaconState, error) {
if state.Slot() <= helpers.StartSlot(2) {
canProcessSlot, err := helpers.StartSlot(2 /*epoch*/)
if err != nil {
return nil, err
}
if state.Slot() <= canProcessSlot {
return state, nil
}

View File

@@ -30,7 +30,7 @@ func TestProcessJustificationAndFinalizationPreCompute_ConsecutiveEpochs(t *test
Epoch: 0,
Root: params.BeaconConfig().ZeroHash[:],
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
JustificationBits: bitfield.Bitvector4{0x0F}, // 0b1111
Validators: []*ethpb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
@@ -67,7 +67,7 @@ func TestProcessJustificationAndFinalizationPreCompute_JustifyCurrentEpoch(t *te
Epoch: 0,
Root: params.BeaconConfig().ZeroHash[:],
},
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
JustificationBits: bitfield.Bitvector4{0x03}, // 0b0011
Validators: []*ethpb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
@@ -107,7 +107,7 @@ func TestProcessJustificationAndFinalizationPreCompute_JustifyPrevEpoch(t *testi
JustificationBits: bitfield.Bitvector4{0x03}, // 0b0011
Validators: []*ethpb.Validator{{ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}, {ExitEpoch: e}},
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
BlockRoots: blockRoots, FinalizedCheckpoint: &ethpb.Checkpoint{},
BlockRoots: blockRoots, FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := beaconstate.InitializeFromProto(base)
require.NoError(t, err)

View File

@@ -68,7 +68,7 @@ func AttestationsDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Valida
return rewards, penalties, nil
}
func attestationDelta(pBal *Balance, v *Validator, prevEpoch uint64, finalizedEpoch uint64) (uint64, uint64) {
func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uint64) (uint64, uint64) {
eligible := v.IsActivePrevEpoch || (v.IsSlashed && !v.IsWithdrawableCurrentEpoch)
if !eligible || pBal.ActiveCurrentEpoch == 0 {
return 0, 0
@@ -182,7 +182,7 @@ func ProposersDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Validator
// Spec code:
// def is_in_inactivity_leak(state: BeaconState) -> bool:
// return get_finality_delay(state) > MIN_EPOCHS_TO_INACTIVITY_PENALTY
func isInInactivityLeak(prevEpoch uint64, finalizedEpoch uint64) bool {
func isInInactivityLeak(prevEpoch, finalizedEpoch uint64) bool {
return finalityDelay(prevEpoch, finalizedEpoch) > params.BeaconConfig().MinEpochsToInactivityPenalty
}
@@ -191,6 +191,6 @@ func isInInactivityLeak(prevEpoch uint64, finalizedEpoch uint64) bool {
// Spec code:
// def get_finality_delay(state: BeaconState) -> uint64:
// return get_previous_epoch(state) - state.finalized_checkpoint.epoch
func finalityDelay(prevEpoch uint64, finalizedEpoch uint64) uint64 {
func finalityDelay(prevEpoch, finalizedEpoch uint64) uint64 {
return prevEpoch - finalizedEpoch
}

View File

@@ -24,8 +24,8 @@ func TestProcessRewardsAndPenaltiesPrecompute(t *testing.T) {
for i := 0; i < len(atts); i++ {
atts[i] = &pb.PendingAttestation{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{},
Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
InclusionDelay: 1,
@@ -122,7 +122,7 @@ func TestAttestationDeltaPrecompute(t *testing.T) {
base, err := epoch.BaseReward(state, i)
assert.NoError(t, err, "Could not get base reward")
assert.Equal(t, uint64(0), rewards[i], "Unexpected slashed indices reward balance")
assert.Equal(t, uint64(3*base), penalties[i], "Unexpected slashed indices penalty balance")
assert.Equal(t, 3*base, penalties[i], "Unexpected slashed indices penalty balance")
}
nonAttestedIndices := []uint64{434, 677, 872, 791}
@@ -202,7 +202,7 @@ func TestAttestationDeltas_ZeroInclusionDelay(t *testing.T) {
pVals, pBal, err := New(context.Background(), state)
require.NoError(t, err)
pVals, pBal, err = ProcessAttestations(context.Background(), state, pVals, pBal)
_, _, err = ProcessAttestations(context.Background(), state, pVals, pBal)
require.ErrorContains(t, "attestation with inclusion delay of 0", err)
}
@@ -214,8 +214,8 @@ func TestProcessRewardsAndPenaltiesPrecompute_SlashedInactivePenalty(t *testing.
for i := 0; i < len(atts); i++ {
atts[i] = &pb.PendingAttestation{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{},
Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x01},
InclusionDelay: 1,
@@ -254,7 +254,7 @@ func TestProcessRewardsAndPenaltiesPrecompute_SlashedInactivePenalty(t *testing.
}
}
func buildState(slot uint64, validatorCount uint64) *pb.BeaconState {
func buildState(slot, validatorCount uint64) *pb.BeaconState {
validators := make([]*ethpb.Validator, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
@@ -287,9 +287,9 @@ func buildState(slot uint64, validatorCount uint64) *pb.BeaconState {
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
BlockRoots: make([][]byte, params.BeaconConfig().SlotsPerEpoch*10),
FinalizedCheckpoint: &ethpb.Checkpoint{},
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{},
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
}

View File

@@ -1,6 +1,8 @@
package precompute
import (
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
@@ -21,8 +23,27 @@ func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, pBal *Balance) err
totalSlashing += slashing
}
minSlashing := mathutil.Min(totalSlashing*3, pBal.ActiveCurrentEpoch)
minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplier, pBal.ActiveCurrentEpoch)
epochToWithdraw := currentEpoch + exitLength/2
vs := state.ValidatorsReadOnly()
var hasSlashing bool
// Iterate through validator list in state, stop until a validator satisfies slashing condition of current epoch.
for _, v := range vs {
if v == nil {
return errors.New("nil validator in state")
}
correctEpoch := epochToWithdraw == v.WithdrawableEpoch()
if v.Slashed() && correctEpoch {
hasSlashing = true
break
}
}
// Exit early if there's no meaningful slashing to process.
if !hasSlashing {
return nil
}
increment := params.BeaconConfig().EffectiveBalanceIncrement
validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
correctEpoch := epochToWithdraw == val.WithdrawableEpoch

View File

@@ -13,7 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessSlashingsPrecompute_NotSlashed(t *testing.T) {
func TestProcessSlashingsPrecompute_NotSlashedWithSlashedTrue(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
Slot: 0,
Validators: []*ethpb.Validator{{Slashed: true}},
@@ -28,6 +28,21 @@ func TestProcessSlashingsPrecompute_NotSlashed(t *testing.T) {
assert.Equal(t, wanted, s.Balances()[0], "Unexpected slashed balance")
}
func TestProcessSlashingsPrecompute_NotSlashedWithSlashedFalse(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
Slot: 0,
Validators: []*ethpb.Validator{{}},
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
Slashings: []uint64{0, 1e9},
})
require.NoError(t, err)
pBal := &precompute.Balance{ActiveCurrentEpoch: params.BeaconConfig().MaxEffectiveBalance}
require.NoError(t, precompute.ProcessSlashingsPrecompute(s, pBal))
wanted := params.BeaconConfig().MaxEffectiveBalance
assert.Equal(t, wanted, s.Balances()[0], "Unexpected slashed balance")
}
func TestProcessSlashingsPrecompute_SlashedLess(t *testing.T) {
tests := []struct {
state *pb.BeaconState

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