Compare commits

...

634 Commits

Author SHA1 Message Date
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
Victor Farazdagi
0a5ec502b0 Updates resyncIfBehind() functionality (#7039)
* defines BestNonFinalized
* updates blocks_fetcher
* updates blocks_queue
* Merge branch 'master' into fix-resync
* Nishant's suggestion
* Merge branch 'fix-resync' of github.com:prysmaticlabs/prysm into fix-resync
* unit test
* Merge branch 'master' into fix-resync
* fixes test
* Merge refs/heads/master into fix-resync
2020-08-18 02:10:45 +00:00
Preston Van Loon
4d463c4a85 Don't ban blocks for context deadlines (#7040)
* Don't ban blocks for context deadlines
* Don't ban blocks for context deadlines
* Add test
* Merge branch 'master' into dont-ban-ctx-deadline2
* fmt
2020-08-18 01:21:10 +00:00
terence tsao
9caa92cae4 Pending queue to handle same slot blocks (#7036)
* Pending queue: rough draft
* Removed extra RUnlock
* apply diff
* Update pending queue tests
* Merge branch 'fix-pending-blocks' of github.com:prysmaticlabs/prysm into fix-pending-blocks
* Merge branch 'master' into fix-pending-blocks
* Comments
* Merge branch 'fix-pending-blocks' of github.com:prysmaticlabs/prysm into fix-pending-blocks
2020-08-18 00:01:32 +00:00
terence tsao
dbd1e8c247 Only cache check point state if it hasn't existed in other cache (#7037)
* Only cache epoch boundary state in the event of skipped epoch boundary slot

* checkpoint

* remove lods

* checkppoint again

* Cache: fill if empty

* Don't include the sync fixes

* Update sync utils

* Avoid extra process slots

Co-authored-by: nisdas <nishdas93@gmail.com>
2020-08-17 16:20:34 -05:00
Victor Farazdagi
bde3073bd6 Wait interval, before finalized peers re-checked (#7032)
* wait on no finalized peers
* Merge branch 'master' into better-no-finalized-peers-handling
2020-08-17 16:01:16 +00:00
Nishant Das
f193dc2f54 Do Not Retrieve From DB For Block Roots (#7028)
* don't use db
2020-08-17 08:41:45 +00:00
terence tsao
a2f781522f Update committee cache size to 32 (#7018)
* Update committee cache size to 32
* Merge branch 'master' into update-committee-cache-size
* Cache: fixed rotating test
* Merge branch 'update-committee-cache-size' of github.com:prysmaticlabs/prysm into update-committee-cache-size
* Merge refs/heads/master into update-committee-cache-size
* Merge refs/heads/master into update-committee-cache-size
* Merge refs/heads/master into update-committee-cache-size
2020-08-17 03:17:46 +00:00
Preston Van Loon
d66f72939e Ignore subscription cancelled warning (#7020)
* Resolve TODO #6449
* Merge refs/heads/master into fix-6449
2020-08-17 01:58:30 +00:00
Preston Van Loon
c3725d11f2 Revert "Sync: Dont ban block roots for context.DeadlineExceeded" (#7017)
* Revert "Sync: Dont ban block roots for context.DeadlineExceeded (#7016)"

This reverts commit a4bbd82a45.
* Merge refs/heads/master into revert-7016-dont-ban-ctx-deadline
2020-08-17 01:18:38 +00:00
terence tsao
715cd40f56 Sync: check blocks and roots lengths (#7019) 2020-08-16 16:48:39 -07:00
Preston Van Loon
a4bbd82a45 Sync: Dont ban block roots for context.DeadlineExceeded (#7016)
* Dont set bad block root if it was context deadline with processing
2020-08-16 19:24:34 +00:00
Nishant Das
0be1957c28 Use Stage 1 For Non Finalized Sync (#7012)
* checkpoint
* dont cancel
* remove
* sync mode
* fixes build
* cap max retries when no finalized peers are found
* use max peers
* change it
* fixes TestService_roundRobinSync/Multiple_peers_with_different_finalized_epoch
* fixes blocks fetcher tests
* fixes blocks queue tests
* fixes TestService_blockProviderScoring test
* gofmt
* Merge branch 'master' into useStage1
* Update round_robin.go

preston's review
* Preston's suggestions
* Merge branch 'useStage1' of github.com:prysmaticlabs/prysm into useStage1
* fixes test
2020-08-16 17:51:14 +00:00
terence tsao
9ebd90c324 Use LRU for checkpoint state cache (#7010)
* DB: add block roots test

* Pool: add seen atts map

* Pool: use seen atts map

* Pool: clear seen map

* Core: optimize InitiateValidatorExit

* Cache: checkpoint state uses LRU

* Cache: use it

* Cache: update tests

* Cache: typo

* Gaz
2020-08-16 07:36:37 -07:00
terence tsao
03c3f06288 Core: optimize InitiateValidatorExit and ProcessAttesterSlashings (#7008)
* Core: optimize InitiateValidatorExit

* Core: optimize

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-15 14:01:46 -05:00
terence tsao
c47d18aa0b Featureflag test: reset init (#7007)
* Featureflag: properly init test
* Merge refs/heads/master into fix-feature-test
2020-08-15 15:48:12 +00:00
Nishant Das
17b810f24e Fix 2nd Stage of Sync (#7006)
* handle 2nd stage better
* 2 stage sort
* add warning
* better processing
* victor's review
* fix one test
* Update beacon-chain/blockchain/receive_block.go
* fixes TestService_roundRobinSync/Multiple_peers_with_many_skipped_slots
* Merge branch 'fixSync' of github.com:prysmaticlabs/prysm into fixSync
* fixes TestService_process
* fixes TestService_blockProviderScoring
* Preston's suggestion
* increase number of available slots, allowing 2nd phase to wrap up
* more concise limits
2020-08-15 15:14:59 +00:00
Nishant Das
ee2ba721ab Initialize Config Correctly (#7004)
* initialize correctly
2020-08-15 01:37:57 +00:00
Noah Citron
d24f99d66d added flag to enable roughtime syncing, with it disabled by default (#6898)
* added flag to enable roughtime syncing, with it disabled by defaults

* gofmt

* switched to feature flag

* enable-roughtime works correctly

* enable-roughtime works correctly

* Gaz

* Remove conflict

* fix roughtime enable

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: rauljordan <raul@prysmaticlabs.com>
2020-08-14 14:22:58 -05:00
Raul Jordan
3c776f4e76 Fix Validator RPC JWT Response (#7001)
* fix jwt response
* fix jwt parse
* ken naming
* gaz
2020-08-14 16:30:11 +00:00
terence tsao
b981442022 Register health APIs handler (#6999)
* 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
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* RPC: register health endpoint
* Gazelle
2020-08-14 15:18:04 +00:00
Victor Farazdagi
6db448a81d Uncomments tests in kv/unaggregated_test (#6997)
* uncomments tests in kv/unaggregated_test
2020-08-14 07:23:42 +00:00
Raul Jordan
f5a1a8b4ed Integrate Validator RPC Server Into Runtime + Add Gateway (#6994) 2020-08-13 19:49:57 -07:00
terence tsao
3df2980cba Add and utilize seen atts map (#6993)
* DB: add block roots test

* Pool: add seen atts map

* Pool: use seen atts map

* Pool: clear seen map

* Gazelle

* Fixed an existing test

Co-authored-by: rauljordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-13 16:52:27 -05:00
Raul Jordan
16c34b627f Add Authentication Functions to Validator RPC (#6968)
* define auth endpoints
* add intercepter with tests
* auth functions
* fix up the auth functions
* add functions for storing and saving the hashed password from the validator db
* validate strong password input and simplify jwt claims
* tests for db funcs
* comments for db funcs
* wrap up the authentication tests
* register auth srv
* use proper db iface package and check if existing password
* fix broken tests and add new test to check if password already exists
* use roughtime
* rlock to check the auth paths
* Merge refs/heads/master into auth-rpc
* Merge refs/heads/master into auth-rpc
* Merge refs/heads/master into auth-rpc
* leave out the stream interceptor
* resolve confs
* Merge branch 'master' into auth-rpc
* confs
* Merge branch 'auth-rpc' of github.com:prysmaticlabs/prysm into auth-rpc
* Merge refs/heads/master into auth-rpc
* Merge refs/heads/master into auth-rpc
* Merge refs/heads/master into auth-rpc
* Merge refs/heads/master into auth-rpc
2020-08-13 20:27:42 +00:00
Ivan Martinez
6ed0539723 Acconuts-V2: Allow importing from any valid keystore, regardless of name (#6992)
* Allow importing from any file

* Fix log

* Add test

* Fix test
2020-08-13 14:45:56 -05:00
Victor Farazdagi
4de0b9fe69 Peer scoring: init sync (#6709)
* refactors redundant part of varname
* introduces score_block_providers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* gazelle
* adds comment
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* removes redundant checks
* add block provider decay test
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* adds case
* penalize inactive peers
* adds scorebadresponses test
* inroduces no-activity penalty
* gazelle
* gofmt
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* expanded tests
* implement SortBlockProviders
* change -> update
* updates block fetcher peer filter
* fixes test
* allows to keep track of peer id
* updates scoring coefficients
* fixes test
* block fetcher update
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* disables empty batch penalty
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* removes outdated code
* update filterPeers
* gazelle
* updates var
* revert changes to var name
* updates blocks_fetcher
* minor fix to import name
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* add max processed blocks cap
* impoves scoring of stale peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* fixes test
* adds weight sorting to scored peers
* return pid when fetching batches
* updates round robin
* gazelle
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* updates block provider decay count
* go tidy
* cherry pick
* fixes test
* go tidy
* Merge branch 'peer-scorer-weighted-sorter' into init-sync-peer-scoring-slow-peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* refactors blocks fetcher: repackage methods
* Merge branch 'refactor-blocks-fetcher' into init-sync-peer-scoring-slow-peers
* minor fixes
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* allow scores in range (0;1) in weighted filter
* filterScoredPeers improve test suite
* puts feature behind the flag
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* fixes tests
* Merge branch 'init-sync-peer-scoring-slow-peers' of github.com:prysmaticlabs/prysm into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Merge branch 'master' into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Update beacon-chain/sync/initial-sync/blocks_fetcher_test.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>
* Nishant's suggestion on peer limit variable
* better explanation of non-blocking peer scoring
* Shay's sugession on peer naming
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Update beacon-chain/sync/initial-sync/blocks_fetcher.go

Co-authored-by: Nishant Das <nishdas93@gmail.com>
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* gofmt
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
* Merge refs/heads/master into init-sync-peer-scoring-slow-peers
2020-08-13 17:33:57 +00:00
Nishant Das
282398fd13 Add in Attestation Validity Check (#6983)
* fix bad bug
* add test
* Merge refs/heads/master into fixAttestationNoVerify
* Merge refs/heads/master into fixAttestationNoVerify
* target
* Merge branch 'fixAttestationNoVerify' of https://github.com/prysmaticlabs/geth-sharding into fixAttestationNoVerify
* add cheap check
* Merge refs/heads/master into fixAttestationNoVerify
* Merge refs/heads/master into fixAttestationNoVerify
* Merge refs/heads/master into fixAttestationNoVerify
* Merge refs/heads/master into fixAttestationNoVerify
* Merge refs/heads/master into fixAttestationNoVerify
2020-08-13 16:58:28 +00:00
Victor Farazdagi
74101612ce Moves AssertLogsContains to assertions package (#6985)
* first working implementation
* assertions tests
* adds to requires
* merges assert and require tests into a single suite
* gazelle
* Merge branch 'merge-assert-require-tests' into assert-logs-contains-move-to-assertions
* gazelle
* updates references
* fixes build issue
* Merge branch 'master' into assert-logs-contains-move-to-assertions
* Merge refs/heads/master into assert-logs-contains-move-to-assertions
* Merge branch 'master' into assert-logs-contains-move-to-assertions
* fixes build issue
* Merge branch 'assert-logs-contains-move-to-assertions' of github.com:prysmaticlabs/prysm into assert-logs-contains-move-to-assertions
* Merge refs/heads/master into assert-logs-contains-move-to-assertions
* Merge refs/heads/master into assert-logs-contains-move-to-assertions
2020-08-13 16:22:25 +00:00
terence tsao
308dbc4272 ListStatuses for validator RPC (#6987)
* DB: add block roots test
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Client: support ValidatorPubkeysToStatuses getter
* RPC: implement ListStatuses
* RPC: tests
* Merge branch 'master' into health-apis
* Update an existing test
* Merge branch 'health-apis' of github.com:prysmaticlabs/prysm into health-apis
* Merge refs/heads/master into health-apis
2020-08-13 15:52:56 +00:00
Ivan Martinez
5705a9a1f9 Accounts-V2: Add test for DeleteAccounts (#6982)
* Add test for DeleteAccounts
* attempt to fix
* Try to fix test
* Remove
* fixed Ivan's test
* Merge branch 'master' into add-delete-test
2020-08-13 15:23:08 +00:00
Nishant Das
72bbc33a65 Fix Validator Exits (#6986)
* add change
* Update beacon-chain/core/blocks/exit.go

Co-authored-by: Shay Zluf <thezluf@gmail.com>
* Merge refs/heads/master into fixExits
2020-08-13 14:37:38 +00:00
Victor Farazdagi
dc752fb945 Merges assert and require tests into a single suite (#6984)
* merges assert and require tests into a single suite
* gazelle
2020-08-13 13:57:29 +00:00
Victor Farazdagi
0c94298847 Peer scorer: fix weighted sorting (#6981)
* peer scorer: fix weighted sorting
* Merge refs/heads/master into minor-fixes-to-peer-scorer
* Merge refs/heads/master into minor-fixes-to-peer-scorer
2020-08-13 09:36:50 +00:00
Victor Farazdagi
7611f6d84a injects peer.ID into requested/queued/fetched batches (#6979)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-13 16:42:21 +08:00
terence tsao
49549f4687 ListBalances for validator RPC (#6975)
* DB: add block roots test

* Node: register RPC service

* RPC: access to client service

* Client: add balances and pubkeys -> indices getters

* Update validator/client/metrics.go

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

* Lint and feedbacks

* Fix lock to prevent a run time panic

* Fixes existing tests

* Validator: add mock for testing

* Validator: Add pubkeys to indices getter

* RPC: tests tests tests

* Lint

* Lint

* Lint

* Lint

* Lint

* Gazelle

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-08-12 18:33:15 -05:00
terence tsao
0d7ea33298 DB: add block roots test (#6974) 2020-08-12 11:28:52 -05:00
Javed Khan
2400536a8e Update sendDepositTx tool (#6972)
* Update sendDepositTx contract address

* Use Medalla config in sendDepositTx

* Update sendDepositTx  - geth not necessary
2020-08-12 22:15:37 +08:00
Victor Farazdagi
da4e96047b go syntax representation of the value in DeepEqual assertions (#6970) 2020-08-12 17:46:56 +08:00
terence tsao
f4d808a542 Validator web RPC skeleton (#6967)
* Proto: remove unused ethapi imports
* Validator: web rpc
* Lint
* Sync with master
* Merge refs/heads/master into web-rpc
* rename
2020-08-12 01:38:01 +00:00
Raul Jordan
86b2bd5edd Implement Accounts-V2 Backup for Direct Keymanager (#6936)
* progress on export feature
* Merge branch 'master' into impl-export
* rename func
* imports
* confs
* export single works
* impl export
* Merge branch 'master' into impl-export
* cleanup exports code
* rename to backup
* rename to backup
* Merge branch 'master' into impl-export
* full test for backup
* Merge branch 'impl-export' of github.com:prysmaticlabs/prysm into impl-export
* gazelle fix
* terence feedback
* merge confs
* Merge branch 'master' into impl-export
* refactor into single select accounts function
* gaz
* Merge refs/heads/master into impl-export
* victor's feedback
* validate yes or no
* confs
* close the zip file in defer
* Merge refs/heads/master into impl-export
* Merge refs/heads/master into impl-export
2020-08-11 23:15:06 +00:00
terence tsao
682401c6b0 Health related web api protos (#6965)
* Proto: first attempt of account related web api protos
* Proto: health related web api protos
* Merge branch 'master' of github.com:prysmaticlabs/prysm into validator-protos-1
* Merge branch 'master' of github.com:prysmaticlabs/prysm into validator-protos-1
* Sync with master
* @rauljordan's feedback
2020-08-11 22:33:03 +00:00
terence tsao
4499fb2ed0 First attempt of account related web api protos (#6964) 2020-08-11 13:23:16 -07:00
terence tsao
46cb3abe2e Add and use genesis time in config (#6966)
* Config: add genesis time and update medalla

* Helper: add GenesisTime getter

* Rest: use the helper
2020-08-11 14:36:32 -05:00
Raul Jordan
11c9699129 Allow Importing One-Off, Private Keys Into Accounts-v2 (#6929)
* import privkey done
* rem print
* tidy
* Merge refs/heads/master into import-priv-key
* Merge refs/heads/master into import-priv-key
* Merge branch 'master' into import-priv-key
* tests pass
* Merge refs/heads/master into import-priv-key
* Merge refs/heads/master into import-priv-key
* resolve confs
* Merge refs/heads/master into import-priv-key
* confs
* Merge refs/heads/master into import-priv-key
* better feedback mechanism
2020-08-11 16:32:05 +00:00
Victor Farazdagi
c24666e02e refactors blocks fetcher: repackage methods (#6962) 2020-08-11 10:15:18 -05:00
Victor Farazdagi
a279f374bc Move to opt-out attestation-aggregation-strategy flag (#6960)
* inverts attestation-aggregation-strategy flag
* Merge refs/heads/master into att-aggregation-opt-out-flag
* marks deprected flag as hidden
* Merge branch 'att-aggregation-opt-out-flag' of github.com:prysmaticlabs/prysm into att-aggregation-opt-out-flag
* Merge refs/heads/master into att-aggregation-opt-out-flag
2020-08-11 12:42:08 +00:00
rkapka
a5f0fd29fc Fix antipatterns (#6961)
* Merge variable declaration and assignment
* Use result of type assertion to simplify cases
* Replace call to bytes.Compare with bytes.Equal
* Drop unnecessary use of the blank identifier
* Replace x.Sub(time.Now()) with time.Until(x)
* Function literal can be simplified
* Use a single append to concatenate two slices
* Replace time.Now().Sub(x) with time.Since(x)
* Omit comparison with boolean constant
* Omit redundant nil check on slices
* Nested if can be replaced with else-if
* Function call can be replaced with helper function
* Omit redundant control flow
* Use plain channel send or receive
* Simplify returning boolean expression
* Merge branch 'origin-master' into fix-antipatterns
* Merge branch 'master' into fix-antipatterns
* Merge branch 'origin-master' into revert-single-channel-antipattern
* Revert "Use plain channel send or receive"

This reverts commit b3108fdc3a.
2020-08-11 12:14:28 +00:00
Nishant Das
b32ccce23d Remove Checked In Metadata File (#6959)
* Delete metaData
2020-08-11 11:26:59 +00:00
Nishant Das
3893ee43f9 support domains in discoveryV5 (#6958) 2020-08-11 18:33:27 +08:00
Ivan Martinez
ea9bb88d13 Accounts-V2: Add command to delete accounts (#6941)
* Add accounts-v2 delete
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-delete-command
* Gaz
* Add confirmation
* Fix build
* Fix test
* Merge branch 'master' into add-delete-command
* Add more cases for exit
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-delete-command
* Fix usage
* Fix logs
* Change to DeleteAccounts
* Remove flag
* Fix comment
2020-08-11 03:54:37 +00:00
terence tsao
537fe3f721 Fix loading historical blocks to replay cold state (#6956)
* Replay: cold state only uses finalized blocks
* Replay: regression test
* Merge refs/heads/master into fix-finalized-replay
2020-08-10 23:35:28 +00:00
Ivan Martinez
8b9138a76a Accounts V2: Log and UX cleanup (#6955)
* Clena up password entry for importing
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-v2-cleanup
* Fix password entry
* Clean
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-v2-cleanup
* Change color
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-v2-cleanup
* Fix
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-v2-cleanup
* Fix
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-v2-cleanup
* Cleanup
* Clean go.mod
* Fix
2020-08-10 22:35:30 +00:00
terence tsao
ceb11f432e Proposer: log graffiti (#6954)
* Proposer: log graffiti
* Merge refs/heads/master into log-graffiti
2020-08-10 19:17:59 +00:00
Raul Jordan
cbc27e0f2e Refactor Wallet Password Handling, Preventing Wallet Corruption (#6933)
* wallet should no longer deal with account passwords
* ensure tests are fixed
* Merge branch 'master' into corrupted-pass
* move mnemonic logic into right place
* rem fmts
* add fileutil
* gazelle
* imports
* move seed logic to derived
* fix tests
* imports
* gaz
* Merge refs/heads/master into corrupted-pass
* merge confs
* Merge refs/heads/master into corrupted-pass
* ivan's feedback
* Merge branch 'corrupted-pass' of github.com:prysmaticlabs/prysm into corrupted-pass
* gaz
* fix shared test
* Merge refs/heads/master into corrupted-pass
* resolve conflicts
* fix test build
2020-08-10 18:54:40 +00:00
Raul Jordan
a7f4293eb3 Resolve Accounts-v2 Feedback (#6953)
* Radek feedback
* Merge refs/heads/master into final-accounts-feedback
* Apply suggestions from code review
* Merge refs/heads/master into final-accounts-feedback
* Merge refs/heads/master into final-accounts-feedback
2020-08-10 18:14:10 +00:00
Shay Zluf
335d31688f Wallet file lock (#6952)
* Wallet file lock

* lock wallet config file only in validator instance

* runtime fixes

* added test

* radek feedback

* fix test
2020-08-10 12:48:41 -05:00
Raul Jordan
95fd399dbe Change Log Level of Genesis Time Info Log in RPC (#6920)
* lvl debug
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* tidy
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* Merge refs/heads/master into change-log-level
* fix log level error
* victor feedback
* Merge refs/heads/master into change-log-level
2020-08-10 16:52:49 +00:00
rkapka
1f21e196b6 Fix multiple anti-patterns from DeepSource analysis (#6951)
* Merge variable declaration and assignment
* Use result of type assertion to simplify cases
* Replace call to bytes.Compare with bytes.Equal
* Drop unnecessary use of the blank identifier
* Replace x.Sub(time.Now()) with time.Until(x)
* Function literal can be simplified
* Use a single append to concatenate two slices
* Replace time.Now().Sub(x) with time.Since(x)
* Omit comparison with boolean constant
* Omit redundant nil check on slices
* Nested if can be replaced with else-if
* Function call can be replaced with helper function
* Omit redundant control flow
* Use plain channel send or receive
* Simplify returning boolean expression
* Merge branch 'origin-master' into fix-antipatterns
* Merge branch 'master' into fix-antipatterns
2020-08-10 16:16:45 +00:00
Preston Van Loon
18b3203f31 Wait for subnet peers before broadcasting onto attestation subnet topic (#6893)
* Initial pass

* Add metric to measure success

* Use a subnet RWLock to prevent duplicate requests, give up after 3 attempts

* push latest commented code

* try with non-blocking broadcast

* Add feature flag, ignore parent deadline if any

* Add slot as metadata

* add tests

* gaz

Co-authored-by: nisdas <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-10 10:27:50 -05:00
rkapka
33105f1bbc Simplify make call by omitting redundant arguments (#6949)
* removed redundant args
* Merge refs/heads/master into omit-redundant-make-args
2020-08-10 11:06:53 +00:00
Victor Farazdagi
44f9d07434 Applies assertion funcs to beacon-chain/core/* tests (#6940)
* beacon-chain/core/blocks/spectest tests updated
* beacon-chain/core/blocks tests updated
* beacon-chain/core/epoch tests updated
* Merge branch 'master' into apply-testutils-assertions-to-core
* beacon-chain/core/helpers tests updated
* beacon-chain/core/validators tests updated
* beacon-chain/core/state/spectest tests updated
* beacon-chain/core/state tests updated
* Merge refs/heads/master into apply-testutils-assertions-to-core
* Merge refs/heads/master into apply-testutils-assertions-to-core
* Merge refs/heads/master into apply-testutils-assertions-to-core
* Merge refs/heads/master into apply-testutils-assertions-to-core
* Merge refs/heads/master into apply-testutils-assertions-to-core
2020-08-10 10:34:33 +00:00
Nishant Das
649bfb58e5 Invert State Locks Flag (#6922)
* invert flag

* Update shared/featureconfig/flags.go

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-10 13:10:41 +08:00
terence tsao
6d5b7b0439 Validator/node: update warn log to error (#6945) 2020-08-09 17:27:23 -07:00
Victor Farazdagi
b241fafd13 Peer scorer: weighted sorting, requests capping, stale peers handling. (#6928)
* cherry pick
* fixes test
* go tidy
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
* Merge refs/heads/master into peer-scorer-weighted-sorter
2020-08-09 20:26:09 +00:00
Nishant Das
b1946ead23 Make Initial Sync Failures Debug (#6930)
* shift to debug logs
* Merge branch 'master' into makeFailuresDebug
* go sum
* Merge branch 'master' into makeFailuresDebug
* Merge branch 'master' into makeFailuresDebug
* Merge refs/heads/master into makeFailuresDebug
2020-08-09 19:47:52 +00:00
terence tsao
7591240366 Revert "Subscriber: use target epoch for hasSeen cache" (#6944)
* Revert "Subscriber: use target epoch for hasSeen cache (#6908)"

This reverts commit 3275a86ece.
2020-08-09 18:52:37 +00:00
Victor Farazdagi
f575a81afd Applies assertion funcs to beacon-chain/core/blocks tests (#6939)
* beacon-chain/core/blocks/spectest tests updated
* beacon-chain/core/blocks tests updated
* Merge refs/heads/master into apply-testutils-assertions-to-core-blocks
* Merge refs/heads/master into apply-testutils-assertions-to-core-blocks
* Merge refs/heads/master into apply-testutils-assertions-to-core-blocks
2020-08-08 19:06:04 +00:00
Victor Farazdagi
fecbec2342 Applies assertion funcs to beacon-chain/db tests (#6938)
* part1
* go tidy
* Merge branch 'go-tidy' into apply-testutils-assertions-to-beaconchain-db
* updated beacon-chain/db/kv tests
* Merge branch 'master' into apply-testutils-assertions-to-beaconchain-db
* Merge refs/heads/master into apply-testutils-assertions-to-beaconchain-db
* Merge refs/heads/master into apply-testutils-assertions-to-beaconchain-db
2020-08-08 18:39:01 +00:00
terence tsao
9a59c4baff Proposer: aggregated unaggregated attestations for block (#6919) 2020-08-08 10:49:02 -07:00
terence tsao
cca439847d Unexport protoarray forkchoice types (#6937)
* Protoarray: un-export all the types

* Protoarray: add proper getters

* Protoarray: update implementations

* Protoarray: update tests

* Protoarray: lint

* Protoarray: lint
2020-08-07 18:37:08 -07:00
Raul Jordan
10f38662e5 Standardize File Permissions in Accounts-V2 (#6934)
* standardize file permissions
* Gaz
* no petname
* Merge refs/heads/master into file-perms
2020-08-07 22:14:07 +00:00
terence tsao
3275a86ece Subscriber: use target epoch for hasSeen cache (#6908)
* Subscriber: use target epoch for hasSeen cache
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
* Merge refs/heads/master into use-target
2020-08-07 20:55:42 +00:00
Victor Farazdagi
43b646a9dd go mod tidy (#6932)
* go tidy
2020-08-07 17:53:40 +00:00
Raul Jordan
1d9374d5c9 Update Prometheus Client (#6921)
* update prom
* Merge refs/heads/master into update-prom
2020-08-07 10:52:50 +00:00
Nishant Das
8100261e70 Log Error Logs Less Frequently (#6923)
* dont log so much

* cleanup

* custom error
2020-08-07 18:06:53 +08:00
Nishant Das
78ec783604 Add New Validator Map Handler (#6910)
* add new method
* Merge branch 'master' into addMapHandler
* comments
* Merge branch 'addMapHandler' of https://github.com/prysmaticlabs/geth-sharding into addMapHandler
* Update beacon-chain/state/types.go

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* Merge refs/heads/master into addMapHandler
* gofmt
2020-08-07 01:42:50 +00:00
Ivan Martinez
6351d187ef Accounts V2: Remove unused passwords-dir and deprecate flag (#6916)
* Remove passwords dir
* Deprecate flag
* Merge branch 'master' of github.com:prysmaticlabs/prysm into remove-passwords-dir
* Properly deprecate flag
* Merge branch 'master' into remove-passwords-dir
* Merge refs/heads/master into remove-passwords-dir
* Merge refs/heads/master into remove-passwords-dir
2020-08-07 00:02:30 +00:00
Raul Jordan
2502b812fc Sort by Derivation Path in File Name When Importing (#6918)
* add sort by derivation in file name

* Update validator/accounts/v2/accounts_import_test.go

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

* imports

* fixed var

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-06 18:40:49 -05:00
terence tsao
ceee7489dd Update SignRequest for key manager (#6917)
* Proto: update sign request fields

* Validator client: aggregate signing

* Validator client: proposal signing

* Validator client: attestation signing

* Validator client: update generic sign

* Proto: use ranges

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-06 18:18:38 -05:00
Raul Jordan
6b4e4bcf96 Fail Immediately if Importing Accounts from Empty Directory (#6915)
* fail on import from empty directory
* Merge refs/heads/master into fail-on-empty-dir
2020-08-06 22:40:14 +00:00
Raul Jordan
96fcb3a927 Fix Pubkey Not Specified Issues in External Keystore Imports (#6914)
* utilize pubkey from privkey if missing pubkey field in keystore
* change tool as well
* Merge refs/heads/master into strange-keystore
* Merge refs/heads/master into strange-keystore
2020-08-06 21:56:25 +00:00
terence tsao
f0de09d2ad Check before saving attestation to pool (#6912)
* Pool: check before save atts
* Pool: test
* Pool: update metrics
* Merge branch 'master' into check-before-save
* Merge refs/heads/master into check-before-save
2020-08-06 21:02:58 +00:00
Raul Jordan
ac82308e03 Allow for Different Language Mnemonic Recovery (#6913)
* allow for different language mnemonics

* imports
2020-08-06 15:33:28 -05:00
terence tsao
5a216de6d2 RPC/proposer: remove dup vs.deleteAttsInPool (#6911) 2020-08-06 11:18:26 -07:00
terence tsao
dc0f2140b3 Rpc service: log error if slasher is not up (#6907)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-06 10:13:09 -07:00
rkapka
1d679c9533 Manual code cleanup (#6906)
* replace fmt.Sprintf with String()

* remove unconditional loop termination

* reapply `break` statements

* replace for loop if statement
2020-08-06 11:29:00 -05:00
Nishant Das
5b75f4e6be add feature config support (#6904) 2020-08-06 20:49:41 +08:00
Preston Van Loon
40b68da486 Add trace spans to GetBlock methods for a better understanding of block proposal delays (#6903)
* Add trace spans to GetBlock methods for a better understanding of block proposal delays
2020-08-06 08:43:46 +00:00
Raul Jordan
ec21316efd Tool for Decrypting/Encrypting EIP-2335 Keystores (#6900)
* begin keystore tool

* add bazel

* keystores tool

* fully decrypt

* implement encrypt

* complete encrypt and decrypt implementations

* finalize tool

* gaz

* fix viz

* help

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-06 00:26:52 -05:00
terence tsao
89bd5f3a5a Add debug endpoint to get inclusion slot (#6895)
* Proto: add GetInclusionSlot

* Proto: build

* Service: add beacon db to struct

* Debug: Implement GetInclusionSlot

* Debug: prevent underflow

* Debug: add tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-05 22:55:39 -05:00
Nishant Das
64ba3c076b Revert "Use Less Intensive Search" (#6899)
* Revert "Use Less Intensive Search (#6848)"

This reverts commit 69e0e302b3.
2020-08-06 02:40:28 +00:00
Noah Citron
440d3288d5 Chain id and netork id flags (#6894)
* added network-id and chain-id flags
* updated usage.go to include new flags
* Merge pull request #1 from prysmaticlabs/master

rebase with master
* gofmt
* Merge branch 'ChainID-and-NetorkID-flags' of github.com:ncitron/prysm into ChainID-and-NetorkID-flags
2020-08-05 22:03:25 +00:00
Shay Zluf
446bfca4f3 Slasher redial (#6889)
* Restart streams on internal error
* debug instead of fatal on retry
* Merge branch 'master' of github.com:prysmaticlabs/prysm into slasher_redial
* goimports
* conn status fix
* Merge branch 'master' into slasher_redial
2020-08-05 21:17:00 +00:00
Ivan Martinez
492944db01 E2E: Add cpu profile and fix logs and sync time (#6872)
* Add cpu profile for beacon node to e2e

* Fix

* Fix again

* Properly kill beacon nodes

* Fix logs

* Try 100%

* Handle cp profile from pprof

* Fix

* Bring expected participation to 98%

* Only enable pprof in non-local running

* Modify sync time

* Fix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-05 09:58:50 -05:00
Preston Van Loon
0d118df034 Check roughtime more frequently when there is a large clock offset (#6879)
* recheck roughtime more frequently if we think our clock is far off
* Merge refs/heads/master into faster-roughtime-corrections
* gaz
* Merge refs/heads/master into faster-roughtime-corrections
* Merge refs/heads/master into faster-roughtime-corrections
* Merge refs/heads/master into faster-roughtime-corrections
2020-08-05 12:31:13 +00:00
rkapka
e492343ffd Code quality issues - Remove unused code (#6864)
* remove unused code

* gofmt

* remove junk file

* bring back metrics-related functions

* bring back keymanager's code
2020-08-05 13:59:46 +02:00
Preston Van Loon
de8d3ec612 Warn users of upcoming breaking change to default value for eth1 provider flag (#6885)
* Increase WARN to ERR. Mention that this flag will have a breaking change in the next release
2020-08-05 08:41:54 +00:00
terence tsao
016b95385a Remove Fuzzit (#6881) 2020-08-04 21:26:13 -07:00
Raul Jordan
ac0237e9cf Return Err in Wallet.HasDir function (#6878)
* fix panic in has dir
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* return err
2020-08-05 02:07:41 +00:00
Ivan Martinez
c860553306 Handle empty local slashing protection data (#6877)
* Add handlers for empty protection data
* Remove copy
* Merge refs/heads/master into fix-isnewattslashable
* Add regression tests
* Merge refs/heads/master into fix-isnewattslashable
* Merge branch 'fix-isnewattslashable' of github.com:prysmaticlabs/prysm into fix-isnewattslashable
* Fix
* Add debug log
2020-08-05 01:03:40 +00:00
Raul Jordan
1f9d155f0e Fix Panic in Wallet HasDir() (#6857)
* fix panic in has dir
* Merge refs/heads/master into has-dir-panic
* Merge refs/heads/master into has-dir-panic
* Merge refs/heads/master into has-dir-panic
* Merge refs/heads/master into has-dir-panic
* Merge refs/heads/master into has-dir-panic
2020-08-04 23:23:15 +00:00
Preston Van Loon
bc883aab9e Return an error when wallet is nil rather than panic (#6875) 2020-08-04 15:53:34 -07:00
Nishant Das
859e59b6f7 Change Sync Error Logs To Debug Logs (#6865)
* switch over to debug logs
* change back
* Change e2e to debug logging
* Merge refs/heads/master into changeToDebug-2
* Merge refs/heads/master into changeToDebug-2
2020-08-04 20:30:40 +00:00
Shay Zluf
0d6fb72496 Slasher protection race condition fix (#6871)
* Slasher lock on update
* gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm into slasher_lock_on_update
* goimports
* line space
* ivan feedback
* Merge refs/heads/master into slasher_lock_on_update
2020-08-04 19:50:23 +00:00
terence tsao
ef69ac4496 Validate attestation: fix error log (#6874)
* attestation: fix  error log
2020-08-04 18:37:35 +00:00
Nishant Das
daedb7411c Fix Justified and Finalized Retrieval in Genesis (#6861)
* fix
* fix tests
* add test
2020-08-04 03:34:17 +00:00
Raul Jordan
6af950f001 Add Back Displaying Deposit Data + Misc Bugs (#6856)
* show deposit data tx
* display
* improve logic for derived
* further improve experience
* imports
* gaz
2020-08-03 20:17:34 +00:00
Raul Jordan
700d82236b Fix Critical Account Keystores Bugs (#6854)
* no need for pass in new account create
* disallow duplicates
* deduplicate and test
* gaz
* fix up broken tests
* unit test for no duplicates
* Merge branch 'master' into fix-account-create
* fix import
* Merge refs/heads/master into fix-account-create
* Merge branch 'fix-account-create' of github.com:prysmaticlabs/prysm into fix-account-create
2020-08-03 18:58:04 +00:00
terence tsao
ee7da0d451 ForceCheckpoint return early when zero hashes (#6852)
* Setter: return early with zero hashes
* Test: zero hashes don't panic
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Merge refs/heads/master into zero-hashes
* Merge refs/heads/master into zero-hashes
* Merge refs/heads/master into zero-hashes
2020-08-03 18:34:54 +00:00
Nishant Das
69e0e302b3 Use Less Intensive Search (#6848)
* use less intensive search
* Add mock method to implement Listener
* Merge refs/heads/master into lessIntensiveSearch
* Merge refs/heads/master into lessIntensiveSearch
2020-08-03 18:10:23 +00:00
terence tsao
d06dcd2eec Update DepositContractFlag default to Medalla (#6853)
* Update medalla deposit contract address
2020-08-03 17:40:05 +00:00
Raul Jordan
593d3daf84 Better Password Input Experience (#6849)
* more sane passwords
2020-08-03 17:05:30 +00:00
Shay Zluf
6582014b80 Fix deposit data copy (#6847)
* fix deposit data copy

* goimports
2020-08-03 16:25:19 +03:00
Nishant Das
e5dde1c6ef fix enrs (#6846) 2020-08-03 20:05:36 +08:00
terence tsao
d3a9b47643 Update medalla bootnodes (#6836)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-02 18:05:08 -05:00
Ivan Martinez
7903ec0b12 Fix CMD Config and modify --historical-slasher-node (#6730)
* Fix CMD config overwriting
* Rename and change historical slasher node
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-cmd-config
* Fix
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Add storage warning
* Merge branch 'fix-cmd-config' of github.com:prysmaticlabs/prysm into fix-cmd-config
* Remove period
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Add default values test
* Merge branch 'fix-cmd-config' of github.com:prysmaticlabs/prysm into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Gaz
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Fix inits
* Merge branch 'fix-cmd-config' of github.com:prysmaticlabs/prysm into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Fix
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-cmd-config
* Fix
* Merge refs/heads/master into fix-cmd-config
* Merge refs/heads/master into fix-cmd-config
2020-08-02 22:09:10 +00:00
Ivan Martinez
22e2278812 Add heap file to E2E artifacts and fix miscalculation for deposit processing (#6657)
* Add heap file to e2e output
* Add comment
* Change to curl
* Gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Run heap at start and end
* Reorder defers
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Fix
* Fix
* Change to logpath
* Attempt
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Fix heap file
* Fix
* Add more beaocn nodes
* Final fixes
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Fix slasher
* Fixes
* Fix
* Fix comment
* Merge branch 'master' into add-heap-e2e
* Merge refs/heads/master into add-heap-e2e
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Fix comment
* Merge branch 'master' into add-heap-e2e
* Merge refs/heads/master into add-heap-e2e
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-heap-e2e
* Fix
* Change memusage to 2gb
* Merge refs/heads/master into add-heap-e2e
* Update endtoend/evaluators/metrics.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-08-02 21:30:59 +00:00
Raul Jordan
eef0d058ec Refactor Direct Keymanager to One-Shot Decrypt (#6823) 2020-08-02 13:02:04 -07:00
Ivan Martinez
37343930dd Change E2E config to test deposits in PR (#6824)
* Change config to allow deposit in PR e2e

* Fix comment

* Fix

* Fix

* Fix

* Fix

* Fix

* Remove pid handling

* Fix build.bazel

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-08-01 12:22:53 -05:00
Nishant Das
002bbf53d0 Remove Custom Genesis Delay (#6827)
* remove custom delay
* gaz
* Merge branch 'master' into removeCustomGenesisDelay
2020-08-01 16:11:36 +00:00
Victor Farazdagi
bf59530d93 Adds block provider scorer (#6756)
* prepares peer scorer collection

* decouples scoring service into separate object

* updates references

* renames package

* removes redundant test init

* gazelle

* gofmt

* updates comment

* fix build

* adds block provider scorer

* score rounding factor constant (per Nishant's suggestion)

* updates penalty applying

* updates score block provider tests

* updates scorer tests

* expand test suite

* get rid of penalties + counters for requested/returned blocks

* removes start score

* fixes provider test

* fixes scorer manager tests

* updates comments

* moves roundScore test function

* maxscore tests

* improves test coverage

* Update beacon-chain/p2p/peers/score_block_providers.go

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

* renames var to make it less ambigous - per Nishant's suggestion

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2020-08-01 12:20:05 +03:00
Nishant Das
0e1fb65476 add bootnodes (#6807)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-31 20:34:44 -05:00
terence tsao
c7c1c660ab Load config after Configure config (#6821)
* Node: load config after configure
* Merge refs/heads/master into load-config
2020-08-01 00:46:55 +00:00
terence tsao
eb0ad0669f Fix empty wallet check (#6819) 2020-07-31 17:08:40 -07:00
Raul Jordan
4dfe02d919 Fix Accounts List Show Deposit Data When Coming From Eth2.0 Deposit CLI (#6811)
* amend accounts list when coming from launchpad
* Merge refs/heads/master into fix-accounts-list
* Merge refs/heads/master into fix-accounts-list
* Merge refs/heads/master into fix-accounts-list
* Merge refs/heads/master into fix-accounts-list
* Merge refs/heads/master into fix-accounts-list
2020-07-31 22:08:13 +00:00
Preston Van Loon
821f2ec029 Accounts V2: Allow user to override password-dir set in the wallet config (#6817)
* Accounts V2: Log a warning when a user specifies --password-dir when it has already been set.
* Override wallet config, as user intended
* gofmt
* Merge refs/heads/master into av2-flag-improvement
2020-07-31 21:20:56 +00:00
Preston Van Loon
dbd2d9a0bb Accounts V2: improve progressbar feedback (#6814)
* Accounts V2: improve progressbar feedback
* gofmt
* Merge refs/heads/master into pb-improvements
2020-07-31 20:46:03 +00:00
Preston Van Loon
3f983e2a96 Accounts V2: Allow for user to specify single file rather than directory for keystore import (#6813)
* Fix public key formatting
* Accounts V2: Allow for user to specify single file rather than directory
* Merge branch 'master' into fix-pubkey-formatting
* Merge refs/heads/master into fix-pubkey-formatting
2020-07-31 20:17:39 +00:00
Raul Jordan
7a1e5b1dd9 Allow spaces in keystore account passwords (#6810)
* allow for spaces in pass
* handle spaces with tests
* Merge refs/heads/master into handle-spaces
2020-07-31 19:50:44 +00:00
Preston Van Loon
bf82683d4f Fix public key formatting (#6809)
* Fix public key formatting
2020-07-31 19:23:08 +00:00
Preston Van Loon
323bf70b85 Add a script to tag docker images as stable or by their git tag version (#6808)
* Add a script to tag docker images as stable or by their git tag version
* Apply suggestions from code review

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
* Always use HEAD
2020-07-31 18:25:14 +00:00
Nishant Das
f414cf36b9 Revert "Reduce E2E idle time to expedite completion (#6762)" (#6793)
* Revert "Reduce E2E idle time to expedite completion (#6762)"

This reverts commit 187cae8290.
* Merge branch 'master' into revertE2EChanges
* fix
* Merge refs/heads/master into revertE2EChanges
* Change size
2020-07-31 02:42:18 +00:00
terence tsao
f7c8ae5aa6 Config flag: onyx (#6789)
* Config/flags: add onyx back
* Sync with master
* Merge refs/heads/master into onyx
* Merge refs/heads/master into onyx
* onyx flag
* Merge refs/heads/master into onyx
* Merge refs/heads/master into onyx
2020-07-31 01:23:37 +00:00
terence tsao
0cced6e41d Roughtime: use debug instead of info log (#6792)
* Roughtime: use debug instead of info log
* Merge refs/heads/master into roughtime-debug
* Merge refs/heads/master into roughtime-debug
2020-07-31 00:00:24 +00:00
Raul Jordan
18f8578d73 Derived Keymanager Has No Need to Store Accounts to Disk (#6790)
* tests pass
* Merge branch 'master' into derive-no-store
* Merge refs/heads/master into derive-no-store
* gaz
* Merge branch 'derive-no-store' of github.com:prysmaticlabs/prysm into derive-no-store
* Merge refs/heads/master into derive-no-store
2020-07-30 23:23:18 +00:00
Raul Jordan
b2ae4243fd Concurrent Decryption of Direct Keymanager Accounts With Progress Bar (#6788)
* progress bar add

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

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

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

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

* fix test

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-30 17:54:15 -05:00
terence tsao
0b77f4f84c Update badge to v0.12.2 (#6740)
* Update badge to v0.12.2
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
* Merge refs/heads/master into terencechain-patch-1
2020-07-30 21:56:36 +00:00
terence tsao
a116502c76 Accounts v2 as default (#6784)
* Featureconfig: invert accounts v2
* Test: fixing validator node
* Test: Fixed node test
* Merge refs/heads/master into account-v2-default
* Merge refs/heads/master into account-v2-default
* Merge refs/heads/master into account-v2-default
* Merge refs/heads/master into account-v2-default
* Merge refs/heads/master into account-v2-default
* Merge refs/heads/master into account-v2-default
2020-07-30 21:00:02 +00:00
Nishant Das
2011896005 Fix Local IP Address (#6781)
* fix local ip
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
* Merge refs/heads/master into fixLocalIP
2020-07-30 20:23:30 +00:00
Raul Jordan
bd7046c790 Improve Speed of Accounts Import (#6785)
* improve speed of import
* better format
* imports
* Merge branch 'master' into fast-import
* Merge refs/heads/master into fast-import
* Merge refs/heads/master into fast-import
* Merge refs/heads/master into fast-import
* Merge refs/heads/master into fast-import
2020-07-30 19:42:16 +00:00
terence tsao
ec4de10001 Add helper ComputeDomainAndSign (#6773)
* Starting
* Merge branch 'master' of github.com:prysmaticlabs/prysm into domain-and-sign
* core blocks tests: updated
* core state tests: updated
* rpc validator tests updated
* sync tests updated
* testutil updated
* Beacon-chain: update tests
* Shared: update tests
* Rest of the tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into domain-and-sign
* Merge refs/heads/master into domain-and-sign
* Merge refs/heads/master into domain-and-sign
* Merge refs/heads/master into domain-and-sign
* Merge refs/heads/master into domain-and-sign
* Sync with master
* Merge branch 'domain-and-sign' of github.com:prysmaticlabs/prysm into domain-and-sign
* Merge refs/heads/master into domain-and-sign
2020-07-30 19:11:22 +00:00
Nishant Das
edc9fcd0d6 Harden Against DOS Attacks (#6780)
* harden
* gaz
* trace log
* Update beacon-chain/p2p/service.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
* yield go-routine
* Merge refs/heads/master into hardenAgainstDOS
* Merge branch 'hardenAgainstDOS' of https://github.com/prysmaticlabs/geth-sharding into hardenAgainstDOS
* Merge refs/heads/master into hardenAgainstDOS
* Merge refs/heads/master into hardenAgainstDOS
* Merge refs/heads/master into hardenAgainstDOS
* Merge refs/heads/master into hardenAgainstDOS
2020-07-30 18:42:22 +00:00
Preston Van Loon
dec779dc1e Disable --enable-eth1-data-majority-vote in e2e (#6787)
* Disable --enable-eth1-data-majority-vote in e2e. See https://github.com/prysmaticlabs/prysm/issues/6786
* Merge refs/heads/master into disable-vote-with-majority
2020-07-30 18:14:07 +00:00
terence tsao
b56f473800 Unskip TestSetupInitialDeposits_1024Entries (#6775)
* Unskip TestSetupInitialDeposits_1024Entries
* Merge refs/heads/master into unskip-init-deposits
* Merge refs/heads/master into unskip-init-deposits
* Merge branch 'master' of github.com:prysmaticlabs/prysm into unskip-init-deposits
* Sync with master
* Merge branch 'unskip-init-deposits' of github.com:prysmaticlabs/prysm into unskip-init-deposits
* Merge refs/heads/master into unskip-init-deposits
* Merge refs/heads/master into unskip-init-deposits
* Merge refs/heads/master into unskip-init-deposits
* Merge refs/heads/master into unskip-init-deposits
2020-07-30 17:38:34 +00:00
Nishant Das
fd0383d17e Update Libp2p Deps (#6782)
* update libp2p deps
* Merge branch 'master' into updateDeps
* tidy
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into updateDeps
* Merge branch 'updateDeps' of https://github.com/prysmaticlabs/geth-sharding into updateDeps
* revert grpc
2020-07-30 16:39:57 +00:00
Ivan Martinez
48bfffbb3e Accounts-V2: Cleanup password entry and disable export (#6778)
* Cleanup prompts
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-accounts-v2
* Fix
* add todo
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-accounts-v2
* Clean
* Merge refs/heads/master into cleanup-accounts-v2
* Merge refs/heads/master into cleanup-accounts-v2
* Change with error
* Merge branch 'cleanup-accounts-v2' of github.com:prysmaticlabs/prysm into cleanup-accounts-v2
* Merge refs/heads/master into cleanup-accounts-v2
* cleanup and remove deposit tx file
* display deposit data
2020-07-30 15:30:19 +00:00
terence tsao
bcea2c1b22 Config/flag: medalla as default (#6770)
* config: use medalla as default

* Tests: align with medalla spec

* Config/flag: deprecate medalla feature flag

* Update shared/featureconfig/flags.go

* Spectest: set genesis forkversion to 0,0,0,0

* Config: set medalla as defat in Configure

* Extra space

* Shard: use copy

* Revert a p2p fork test

* Update default medalla for tools

* Use medalla config for e2e

* Fix E2E

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>
2020-07-30 08:45:00 -05:00
Ivan Martinez
187cae8290 Reduce E2E idle time to expedite completion (#6762)
* Make changes to E2E to finish faster

* rename

* Fix

* reduce slots per epoch

* Remove process ID

* Fix

* Fix

* Fix

* Remove pid handling

* Fix build

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-29 21:58:30 -05:00
Nishant Das
353bec600f Fix Handshake (#6776)
* remove security issue
* Merge branch 'master' into fixHandshake
2020-07-30 01:04:35 +00:00
Raul Jordan
bde18f0329 Resolve Remaining Accounts Bugs (#6769)
* fix cases
* fix up imports
* ask until successful
* fixed imports flow
* fully utilize progress bar
* tidy
* grpc
* add round trip test fix
* properly use seeds
* update deps
* update deps
* tidy
* rem print
* fix bazel tests
* rem extraneous log
* gaz
* go mod tidy
* grpc version
* fix deps
* Merge branch 'master' into empty-or-nonexistent
* deps
* tidy
* option show bytes
* Merge refs/heads/master into empty-or-nonexistent
2020-07-29 23:54:23 +00:00
Raul Jordan
62c92af247 Remove Deprecated SSZ Decode Edge Case for BeaconBlocksByRoots (#6771)
* remove temp unmarshal edge case
* removed deprecated func
* final err fix
* Merge refs/heads/master into fix-exploit
2020-07-29 23:15:14 +00:00
Raul Jordan
f9a08dd5d2 Revert "Update Ethereumapis" (#6772)
* Revert "Update Ethereumapis (#6761)"

This reverts commit e94e62b98f.
2020-07-29 22:23:13 +00:00
Nishant Das
ecf197c11e Update Pubsub Parameters (#6744)
* initial commit

* fix

* lint

* clean up

* fix bug
2020-07-29 11:14:15 -05:00
Victor Farazdagi
84697a0a59 Adds peer scorer manager (#6752)
* prepares peer scorer collection
* decouples scoring service into separate object
* updates references
* renames package
* removes redundant test init
* gazelle
* gofmt
* Merge branch 'master' into peer-scorer-manager
* updates comment
* fix build
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
* Merge refs/heads/master into peer-scorer-manager
2020-07-29 09:26:46 +00:00
Raul Jordan
e5f3a30226 Allow Relative Imports in Accounts-v2 (#6758)
* add abs imports tests

* relative imports now work

* misc

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-29 11:33:28 +03:00
Preston Van Loon
e94e62b98f Update Ethereumapis (#6761)
* Update Ethereumapis
* Merge refs/heads/master into update-ethereumapis-1
* Merge refs/heads/master into update-ethereumapis-1
2020-07-29 06:03:52 +00:00
terence tsao
d6eb6d3f41 Move ValidateAttestationTime earlier for sync (#6755)
* Move time checks to the start
* Merge branch 'master' of github.com:prysmaticlabs/prysm into check-time-first
* Merge refs/heads/master into check-time-first
* Merge refs/heads/master into check-time-first
* Merge refs/heads/master into check-time-first
* Merge refs/heads/master into check-time-first
* Merge refs/heads/master into check-time-first
2020-07-29 05:31:50 +00:00
Ivan Martinez
fac5e19a17 Accounts-V2: Replace promptui with shared/promptutil (#6759)
* Add promptutil to shared/promptutil
* fixes
* comment
* Implement promptutil into accounts-v2
* gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm into implement-promptutil
* Apply suggestions from code review
* gofmt and fix all scanned input
* Merge refs/heads/master into implement-promptutil
2020-07-29 04:55:26 +00:00
Fabrice Cheng
cbd731152e Return INVALID validator status if the BLS signature is invalid (#6576)
* return INVALID status if BLS signature is invalid

* add unit tests for VerifyDepositSignature function

* fix lint

* lint fix

* gazelle run run

* update ethereumapis dependencies in go module

* tidy go mod

* update VerifyDepositSignature function to use the proper way of generating sig

* update tests

* update gazelle

* add ValidatorStatus test

* update to Warn

* reorder impot

* merge verifyDepositDataSigningRoot with VerifyDepositSignature

* refactor one last time

* align with specs for computing Domain

* add warn error logs
2020-07-28 23:19:07 -05:00
Ivan Martinez
fc0585f724 Add promptutil to shared/promptuil (#6757)
* Add promptutil to shared/promptutil
* fixes
* comment
2020-07-29 03:04:14 +00:00
Raul Jordan
9d08ba49de Accounts Revamp Fixes: "Overall" Wallet Improvements (#6736)
* change default wallet dir path to not be hidden

* gaz + pass wallet dir

* gaz + move const to flags

* move to flags

* move to flags

* use filepath join in order to create a valid dir name

* add wallet dir

* return err no wallet found issues

* fix up edit remote

* all tests passing

* fix test

* create or open wallet

* ivan feedback

* enter password for account with pubkey

* Update validator/accounts/v2/accounts_create.go

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

* works

* preston feedback

* nothing to export

* fmt

* test for create or open

* gaz

Co-authored-by: shayzluf <thezluf@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
2020-07-28 20:20:13 -05:00
Preston Van Loon
1a1c1bb813 Return 503 on healthz with error (#6754)
* Return 503 on healthz with error
* fix other test
* Update shared/prometheus/service_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-07-29 00:31:21 +00:00
Ivan Martinez
3a609f44b9 Accounts-V2: Minor fixes for logging (#6751)
* Fixes for accounts-v2
* Merge branch 'master' into fixes
* Undo wallet changes
* Merge branch 'fixes' of github.com:prysmaticlabs/prysm into fixes
* Merge refs/heads/master into fixes
2020-07-28 22:58:11 +00:00
terence tsao
c0d6a231bf Faster ancestor root look up via fork choice store (#6753)
* forkchoice: add `HasParent` and `AncestorRoot` getters
* Tests
* Interfaces
* process block: use getters in `ancestor`
* Update tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into faster-ancestor-block
* feedback from @rauljordan
2020-07-28 22:29:34 +00:00
rkapka
becb0b19e2 Voting With The Majority (#6644)
* eth1DataMajorityVote draft
* Merge branch 'origin-master' into eth1-majority-voting
* small test change
* move minimal config's HeadOfVotingPeriodLength closer to sqroot(32)
* remove todo
* remove head period and simplify equality check
* extract private functions from eth1DataMajorityVote
* feature flag
* Merge branch 'origin-master' into eth1-majority-voting
* add bytes import to tests
* Merge branch 'master' into eth1-majority-voting
* re-run build
* Merge branch 'master' into eth1-majority-voting
* Merge branch 'master' into eth1-majority-voting
* Merge branch 'master' into eth1-majority-voting
2020-07-28 20:29:12 +00:00
Ivan Martinez
ee1adddd24 Accounts V2: Fix issues reported by rkapka (#6725)
* Fix accounts v2 runtime
* Accounts V2: Fix issues found by rkapka
* Add to help
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Fixes
* add back error
* Make new wallet error cleaner
* Fix text
* Fix log
* Add case for normal error
* Update validator/flags/flags.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Fix comment
* Merge refs/heads/master into fix-v2-runtime
* fix comment
* Fix test
* Merge branch 'master' into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
* Merge refs/heads/master into fix-v2-runtime
2020-07-28 19:23:53 +00:00
Preston Van Loon
06ee5695fb Save finalized checkpoint on beacon chain close (#6431)
* Save finalized checkpoint on save

* gofmt and goimport

* remove head.root arg

* test

* fixes

* remove comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-28 13:35:17 -05:00
terence tsao
027ee4c18c Add a ComputeDomainVerifySigningRoot helper (#6743)
* Add ComputeDomainVerifySigningRoot
* Update validate aggregate proof signatures to use it
* Update verify proposer slashing to use it
* Update test to use it
* Merge branch 'master' into domain-and-signingroot
* Quick fix on test
* Merge branch 'domain-and-signingroot' of github.com:prysmaticlabs/prysm into domain-and-signingroot
* Merge branch 'master' of github.com:prysmaticlabs/prysm into domain-and-signingroot
* Merge refs/heads/master into domain-and-signingroot
* Merge refs/heads/master into domain-and-signingroot
2020-07-28 16:49:47 +00:00
Nishant Das
8a69d34b96 Fix Accounts Creation Error (#6748)
* add check
* Merge refs/heads/master into fixAccountsError
* Merge refs/heads/master into fixAccountsError
2020-07-28 16:06:18 +00:00
Nishant Das
7861005990 Allow Multiple Selection For Exports (#6749)
* add changes
* Merge branch 'master' into fixExports
* last request
* Merge branch 'fixExports' of https://github.com/prysmaticlabs/geth-sharding into fixExports
2020-07-28 15:31:37 +00:00
Ivan Martinez
607d5fdf4e Accounts-V2: Change accounts-v2 import to use directory of keystores (#6742)
* Finish implementation of importing dir of keystores

* Fix

* Fix importing

* Finish testing import account

* Update validator/accounts/v2/accounts_import.go

* Fix

* Fix

* fix

* Fix prompt

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-07-28 09:18:22 -05:00
Ivan Martinez
0cd80bb970 Accounts-V2: Change keystore filename to include timestamp (#6741)
* Change keystore filename to include timestamp
* Fix test
* Merge branch 'master' into change-keystore-filename
* Fix comment
* Merge branch 'change-keystore-filename' of github.com:prysmaticlabs/prysm into change-keystore-filename
* Request comments
* Comment
* Add comment
* Fix test
* Fix test
* Add test for AccountTimestamp
2020-07-28 00:02:29 +00:00
Shay Zluf
a867f6175b Make external slasher protection fail on load if slasher is not reachable (#6704)
* external slasher protection fails loudly
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge branch 'master' of github.com:prysmaticlabs/prysm into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* Merge refs/heads/master into external-slasher-fail-loud
* ivan feedback
* Merge branch 'external-slasher-fail-loud' of github.com:prysmaticlabs/prysm into external-slasher-fail-loud
* lint fix
* ivan feedback
2020-07-27 20:06:49 +00:00
terence tsao
905a57cbd7 Fix checkForChainStart pre-genesis state and 0 validator (#6739) 2020-07-27 10:35:01 -07:00
Ivan Martinez
7fff4ec411 Accounts V2: Add --num-accounts to HD wallet commands (#6721)
* Add num-accounts to wallet recover and account create for derived wallets

* Fix

* Test derived accounts

* Stuff

* Gaz

* Fix

* Fix

* Fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-27 09:03:30 -05:00
Nishant Das
664349e553 Account for Bad Blocks in Gossip (#6726)
* add bad block cache

* terence's review

* terence's review

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-27 19:57:19 +08:00
terence tsao
3a852bc032 eth1 chain ID and network checks (#6727)
* Add config
* Update config values
* Add checks
* Merge refs/heads/master into eth1network
* Merge refs/heads/master into eth1network
* Update e2e test config for devnet
* Merge branch 'eth1network' of github.com:prysmaticlabs/prysm into eth1network
2020-07-27 04:48:36 +00:00
Victor Farazdagi
630cbfb1b6 Fixes issue with concurrent map writes in gossipsub (#6731)
* Fixes issue with concurrent map writes in gossipsub
* Merge refs/heads/master into fix-concurrent-map-write-in-pubsub
2020-07-27 00:56:55 +00:00
terence tsao
ca04621849 saveHeadNoDB does not invalidate hot state cache (#6729) 2020-07-26 17:10:35 -07:00
Nishant Das
c8761ffb18 Revert "Update rules go to v0.22.9 (#6712)" (#6724)
This reverts commit efc24f6aab.
2020-07-26 12:28:42 +08:00
Nishant Das
2cd359bde5 preset memory (#6722) 2020-07-25 11:54:54 -07:00
Nishant Das
7a12fc6d75 Fix Metadata Sequence Checks (#6711)
* checkpoint

* Update beacon-chain/sync/rpc_test.go

* change conditional

* fix test

* fmt

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-25 11:53:41 -05:00
Nishant Das
ada351d087 Applies Assertion And Require Test Functions to Powchain (#6652)
* change all tests
* save
* fix tests
* Update deposit_test.go
* Update deposit_test.go
* Update log_processing_test.go
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* fix failing test
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
* Merge refs/heads/master into powchainAssert
2020-07-25 06:20:21 +00:00
terence tsao
d114c6c6b7 Update comments for get_committee_count_per_slot (#6717)
* Update comment
* Merge branch 'master' into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
* Merge refs/heads/master into epochwise_committee_count_per_slot
2020-07-25 05:29:30 +00:00
terence tsao
01f3a6e6db Update on block/attestation comments (#6720)
* Update on att comments
* Update on block comments
* Merge refs/heads/master into forkchoice-comments
* Merge refs/heads/master into forkchoice-comments
2020-07-25 04:55:42 +00:00
Preston Van Loon
efc24f6aab Update rules go to v0.22.9 (#6712)
* bump rules_go

* reapply patch, remove commented code

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-25 12:14:17 +08:00
Preston Van Loon
715a33532d Update ethereumapis (#6719)
* Update ethereumapis
* go mod tidy
* Merge refs/heads/master into update-ethereumapis
2020-07-25 01:03:59 +00:00
terence tsao
366e53c416 Add committee ID check to process attestation (#6718) 2020-07-24 17:12:15 -07:00
Preston Van Loon
e1f33b196d Update spectests to v0.12.2 (#6713)
* Update spectests to v0.12.2
* Update readme to v0.12.2
* Revert "Update readme to v0.12.2"

This reverts commit 34461a1d05.
* Merge branch 'master' into update-spectests-v0.12.2
* fix config path
* Merge refs/heads/master into update-spectests-v0.12.2
2020-07-24 22:25:31 +00:00
Raul Jordan
55009bfa66 Fix Validator Accounts-V2 Runtime (#6714)
* fix accounts v2 runtime
2020-07-24 21:36:28 +00:00
terence tsao
0b9212c685 Revert "Optimize AppendValidator for beacon state" (#6710)
* Revert "Optimize `AppendValidator` for beacon state (#6659)"

This reverts commit c41e382255.
* Test. H/t to @prestonvanloon
* Merge branch 'master' of github.com:prysmaticlabs/prysm into revert-6659-deposit
* Merge branch 'master' into revert-6659-deposit
2020-07-24 05:43:15 +00:00
terence tsao
403dab43f5 Use config DepositContractTreeDepth (#6708) 2020-07-23 21:30:28 -07:00
Ivan Martinez
dfdff37a3e Accounts V2: Fix import command (#6707)
* Fix import
* Merge branch 'master' into fix-import-v2
* Fix
* Merge branch 'fix-import-v2' of github.com:prysmaticlabs/prysm into fix-import-v2
* Fix for comments
* Merge refs/heads/master into fix-import-v2
* Merge branch 'master' into fix-import-v2
2020-07-24 03:19:28 +00:00
Ivan Martinez
3974104a20 Accounts V2: Rename new->create, rename files and usage text fixes (#6695)
* Accounts V2: Renames and usage text fixes

* Fix
2020-07-23 21:18:36 -05:00
Raul Jordan
a5b408769a Accounts V2: Resolve Remaining Keymanager Bugs (#6706)
* v2 fix bugs
* better doc
* include wallet build fix
* fixed broken list test
* add round trip recover seed unit test
* imports
* implement list with tests
* add altona flags
* tests for unicode
* added is valid unicode tests
* fixed up tests to ensure wallet is persisted after everything works
* resolve confs and integrate medalla testnet
* fix build
* add medalla
* fixed import spacing
2020-07-24 00:43:01 +00:00
terence tsao
cc773a1641 Rm unused HashTreeRootState (#6697)
* Remove hash tree root implementations

* Delete benchmark tests

* Update existing tests

* Gaz

* Remove outdated ssz cache fuzz test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-23 17:19:05 -05:00
Jim McDonald
415cb9ff8d Add medalla testnet configuration. (#6700) 2020-07-23 14:56:39 -05:00
Preston Van Loon
2c11fcb242 Stategen: always invalidate hot cache state in StateByRootInitialSync (#6698)
* Stategen: always invalidate hot cache state in StateByRootInitialSync
* Sanity test. @nisdas feedback
* Merge refs/heads/master into defer-invalidate
2020-07-23 04:25:50 +00:00
Ivan Martinez
c72db6f96a Accounts V2: Refactor prompts, deduplicate into directory and password (#6674)
* Refactor input code, deduplicate into directory and password
* Change to filepath
* Rename
* Make consts visible to whole validator package
* Fix
* Try commands and fix
* Fix defaults
* Fixes
* Merge branch 'master' into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Remove consts and add comment
* Merge branch 'refactor-input-prompts' of github.com:prysmaticlabs/prysm into refactor-input-prompts
* Undo
* Fixes
* Update validator/accounts/v2/prompt.go
* Merge refs/heads/master into refactor-input-prompts
* gofmt
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Merge branch 'master' into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Fix
* Merge refs/heads/master into refactor-input-prompts
* Merge refs/heads/master into refactor-input-prompts
* Accounts V2: Simplify Wallet Save/Read To and From Disk Functions (#6686)

* simplify wallet functions

* fix build

* futher simplify wallet

* simplify read/write methods

* move direct functions to direct keymanager

* further move direct km specific funcs

* cleanup

* simplify the direct tests

* fixed tests

* lint

* further simplify

* tidy

* fix config write

* fixed test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* conflict resolution
* trim
2020-07-23 03:10:23 +00:00
Raul Jordan
7c52ef8c2b Accounts V2: Simplify Wallet Save/Read To and From Disk Functions (#6686)
* simplify wallet functions

* fix build

* futher simplify wallet

* simplify read/write methods

* move direct functions to direct keymanager

* further move direct km specific funcs

* cleanup

* simplify the direct tests

* fixed tests

* lint

* further simplify

* tidy

* fix config write

* fixed test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-22 21:12:51 -05:00
Victor Farazdagi
0006377aec Applies assertion funcs to validator tests (#6694)
* Applies assertion funcs to validator/keymanager/v1 tests
* gazelle
* Applies assertion funcs to validator/keymanager/v2 tests
* Applies assertion funcs to validator/misc tests
* Applies assertion funcs to validator/misc tests
* Merge branch 'master' into validator-apply-testutils-assertions
* gazelle
* Merge branch 'master' into validator-apply-testutils-assertions
* Merge branch 'master' into validator-apply-testutils-assertions
* Merge refs/heads/master into validator-apply-testutils-assertions
2020-07-23 01:13:52 +00:00
Preston Van Loon
208659d7f5 Enable local slashing protection by default (#6687)
* Enable local slashing protection by default
* Merge refs/heads/master into enable-local-protection-by-default
* Merge refs/heads/master into enable-local-protection-by-default
* Merge refs/heads/master into enable-local-protection-by-default
* Merge refs/heads/master into enable-local-protection-by-default
* Merge refs/heads/master into enable-local-protection-by-default
* Merge refs/heads/master into enable-local-protection-by-default
2020-07-23 00:47:19 +00:00
Ivan Martinez
cf57db910c Accounts V2: Remove traces from command errors (#6692)
* Remove traces from errors for accounts command
* Merge refs/heads/master into remove-stack
* Merge refs/heads/master into remove-stack
* Merge refs/heads/master into remove-stack
* Merge refs/heads/master into remove-stack
* Merge refs/heads/master into remove-stack
2020-07-23 00:11:00 +00:00
Ivan Martinez
73a9429f1e Accounts V2: Remove CanUnlockAccounts from Wallet (#6693)
* Remove CanUnlockAccounts from Wallet
* Merge refs/heads/master into remve-canunlockaccounts
* Merge refs/heads/master into remve-canunlockaccounts
* Merge refs/heads/master into remve-canunlockaccounts
2020-07-22 23:26:39 +00:00
Raul Jordan
cab89c37f1 Accounts V2: Remove Mnemonic Confirm From Direct Keymanager (#6696)
* remove mnemonic from direct
* Merge refs/heads/master into remove-mnemonic-direct
2020-07-22 22:52:31 +00:00
Ivan Martinez
7d80415089 Move deposit utils to depositutil package (#6690)
* Move deposit utils to depositutil package
* gofmt
* Gaz
* Merge refs/heads/master into move-deposit-utils
* Merge refs/heads/master into move-deposit-utils
2020-07-22 22:21:41 +00:00
Preston Van Loon
f19770a393 Revert "Add Github Superlinter" (#6691)
* Revert "Add Github Superlinter (#6677)"

This reverts commit 6270347fdb.
* Merge refs/heads/master into revert-6677-rauljordan-patch-1
2020-07-22 21:48:04 +00:00
rkapka
95efcb6410 Applies assertion funcs to forkchoice tests (#6685)
* refactored 3 files
* refactored the rest of files
* Merge branch 'origin-master' into refactor-forkchoice-tests
* gazelle fix
* Merge branch 'master' into refactor-forkchoice-tests
* Merge branch 'master' into refactor-forkchoice-tests
* Merge branch 'master' into refactor-forkchoice-tests
2020-07-22 21:11:03 +00:00
Raul Jordan
6270347fdb Add Github Superlinter (#6677)
* Add Github Superlinter

This PR adds the Github superlinter to our codebase as a Github action. Resolves #6308.
* Apply suggestions from code review
* Merge refs/heads/master into rauljordan-patch-1
* fix action
* Merge refs/heads/master into rauljordan-patch-1
* Merge refs/heads/master into rauljordan-patch-1
* Merge refs/heads/master into rauljordan-patch-1
* Merge refs/heads/master into rauljordan-patch-1
* Merge refs/heads/master into rauljordan-patch-1
2020-07-22 20:22:26 +00:00
Victor Farazdagi
e5b7c3f3e6 Applies assertion funcs to validator/keymanager tests (#6683)
* Applies assertion funcs to validator/keymanager/v1 tests
* gazelle
* Applies assertion funcs to validator/keymanager/v2 tests
* Merge refs/heads/master into validator-keymanager-apply-testutils-assertions
* Merge refs/heads/master into validator-keymanager-apply-testutils-assertions
2020-07-22 19:42:43 +00:00
terence tsao
6c408d31df Remove unused protos and operations (#6684)
* Remove attestation containers

* Remove unused last votes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-22 14:05:41 -05:00
Victor Farazdagi
4400321081 Handles case when no peers with finalized blocks are found (#6679)
* Handles case when no peers with finalized blocks are found
* more tests
* Merge branch 'master' into handle-zero-block-init-sync
* Merge branch 'master' into handle-zero-block-init-sync
2020-07-22 18:14:24 +00:00
terence tsao
17f845dcb0 Update head before send feed (#6681)
* Update head before state feed
* Test
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update-head
2020-07-22 17:05:17 +00:00
Preston Van Loon
62ae22e3f9 Use correct context for chainHeadRetrieval (#6678)
* Use correct context for chainHeadRetrieval
* Merge refs/heads/master into fix-context
2020-07-22 16:20:20 +00:00
Nishant Das
647599e87f fix for virtual networks (#6676) 2020-07-22 10:44:17 -05:00
Raul Jordan
4017743f7f Accounts V2: Refactor Wallet Open / Close and Keymanager Initialization (#6668)
* refactoring create account

* dep

* much easier, create a derived account by simply unlocking wallet

* revert changes to new

* make open wallet smarter and utilize cli ctx

* remove the wallet config

* successfully build

* simplify ctx creation for tests

* tests should pass individually

* tests pass

* fixed up to allow for wallet password file input

* fix broken tests

* formatting

* fmt

* simplify recover

* fixed up tests

* implicit use of default wallet path working

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-21 23:49:04 -05:00
Preston Van Loon
28096a846e Better gRPC retry including stream retry (#6670)
* Add gRPC retry delay, apply retry and delay to streams

* gofmt, fix flag

* lint

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-21 22:45:52 -05:00
Ivan Martinez
e0d11ff1d2 Accounts V2: Wallet Recover (#6661)
* Implement derived wallet recover
* Fix log
* Fix tests
* Comments
* Merge branch 'master' of github.com:prysmaticlabs/prysm into derived-recover
* Remove log
* Comments
* Fix fatal
* add comment
* Merge refs/heads/master into derived-recover
* Merge refs/heads/master into derived-recover
* Merge refs/heads/master into derived-recover
* Merge refs/heads/master into derived-recover
2020-07-22 02:41:39 +00:00
Ivan Martinez
8a65af168d Accounts V2: Change fatal logs to return errors (#6672)
* Change logging out errors to returns
* Merge branch 'master' of github.com:prysmaticlabs/prysm into change-logs-to-return
* Lint
* Merge branch 'master' into change-logs-to-return
2020-07-22 02:04:08 +00:00
terence tsao
d1a828ad87 Rm archival service db usages and proto definitions (#6671) 2020-07-21 17:04:46 -07:00
Preston Van Loon
f1cfb6a222 Update go-ethereum (#6660)
* Update go-ethereum
* fix go-ethereum
* Merge branch 'master' into update-go-ethereum
* Merge refs/heads/master into update-go-ethereum
* Merge refs/heads/master into update-go-ethereum
* Merge refs/heads/master into update-go-ethereum
2020-07-21 21:52:19 +00:00
Raul Jordan
3023f5dbd3 Accounts V2: Derived Keymanager Sign (#6667)
* amend derived with secret keys cache
* all tests for sign
* Merge branch 'master' into sign-derived
* formatting
* Merge branch 'sign-derived' of github.com:prysmaticlabs/prysm into sign-derived
* initialize
* use seed
* fix build
* Merge refs/heads/master into sign-derived
* Merge refs/heads/master into sign-derived
* Update validator/keymanager/v2/derived/derived.go
2020-07-21 21:15:47 +00:00
terence tsao
c41e382255 Optimize AppendValidator for beacon state (#6659) 2020-07-21 12:58:30 -07:00
Preston Van Loon
784f4169ef Check gossip message decoded length before decoding (#6663)
* Check gossip message decoded length before decoding
* gofmt
* Merge refs/heads/master into snappy-decodedlen-check
* Merge refs/heads/master into snappy-decodedlen-check
* Merge refs/heads/master into snappy-decodedlen-check
* @nisdas feedback
2020-07-21 19:14:34 +00:00
terence tsao
367738e83b Remove unused attestation operations in DB (#6664)
* Remove attestation usages in DB
* Merge refs/heads/master into rm-unused
* Merge refs/heads/master into rm-unused
* Fixed export wrapper
* Merge branch 'rm-unused' of github.com:prysmaticlabs/prysm into rm-unused
2020-07-21 18:17:33 +00:00
Victor Farazdagi
ca54c1d480 Applies assertion funcs to validator/client tests (#6654)
* Applies assertion funcs to validator/client tests
* gazelle
* Merge branch 'master' into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
* Merge refs/heads/master into validator-client-apply-testutils-assertions
2020-07-21 13:02:21 +00:00
Raul Jordan
e97d310453 Accounts V2: Derived Keymanager List Accounts (#6662)
* begin on list derived accounts
* begin on list derived accounts
* continued work on listing derived accounts
* deterministic pet name
* petnames
* finished list
* display deposit data
* lint
* use direct km
* tidy
* begin on revising tests for accounts list
* fix direct list test
* gaz
* tests all passing for derived list
* gaz
2020-07-21 05:06:11 +00:00
Raul Jordan
bc16fa9f50 Accounts V2: Derived Keymanager, Wallet & Account Creation (#6624)
* initialize derived wallet
* derived wallet + account creation
* initialize wallet seed
* encrypted seed file creation
* generate next acct
* create seed from pass
* properly creating derived accounts
* fix up formatting
* prep for review
* start tests for derived create account
* add derived test
* linter
* gaz
* derived keymanager create account test complete
* Merge branch 'master' into derived-keymanager
* tests pass
* gaz
* fix list test
* Merge refs/heads/master into derived-keymanager
* ivan feedback
* skip mnemonic confirm
* Merge branch 'derived-keymanager' of github.com:prysmaticlabs/prysm into derived-keymanager
* comment
* tidy
* fmt
* organize
* test interface conformity
* Update validator/accounts/v2/iface/wallet.go
* ivan comments
* Merge branch 'derived-keymanager' of github.com:prysmaticlabs/prysm into derived-keymanager
* Merge refs/heads/master into derived-keymanager
* Merge branch 'master' of github.com:prysmaticlabs/prysm into derived-keymanager
* Fix
* Fix test
* Merge refs/heads/master into derived-keymanager
* fix errs
* imports
* Gaz
2020-07-21 02:05:23 +00:00
Victor Farazdagi
9deeb592e6 Adds type info into equality assertions (#6656)
* Adds type info into equality assertions
* tests
* reorder got/want
* more tests
* Merge refs/heads/master into assertions-better-error-reporting
* Merge refs/heads/master into assertions-better-error-reporting
* Merge refs/heads/master into assertions-better-error-reporting
2020-07-21 00:47:53 +00:00
Ivan Martinez
93bbb86a30 Accounts-V2: Add tests for exporting and importing (#6615)
* Add test for exporting and importing
* Add test for non-interactive
* Test import cli
* Merge branch 'master' of github.com:prysmaticlabs/prysm into test-export
* Merge branch 'master' into test-export
* Cleanup tests a bit
* Change to assert
* Fix tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into test-export
* Fix comment, change constants
* Fixes
* Change to require
* Fix broken test
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
* Merge refs/heads/master into test-export
2020-07-20 21:12:46 +00:00
Ivan Martinez
d54663a553 Add --historical-slasher-node flag to simplify slasher usage (#6627)
* Add historical-slasher-node flag
* Fix build
* Remove useless flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Fix flag
* Merge branch 'add-flasher-flag' of github.com:prysmaticlabs/prysm into add-flasher-flag
* Add flags to beacon chain
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
* Merge refs/heads/master into add-flasher-flag
2020-07-20 20:23:48 +00:00
terence tsao
0488c9869e Init sync batch block clean up (#6599) 2020-07-20 12:35:30 -07:00
Victor Farazdagi
f0ffd5af03 Introduces peer scorer service (#6579)
* introduces peer scorer service
* gazelle
* Merge branch 'master' into peer-scoring-service
* fixes comment
* fix build error
* linter suggestions
* Merge branch 'master' into peer-scoring-service
* updates tests
* Merge branch 'master' into peer-scoring-service
* badresponses scorer tests
* gazelle
* Merge branch 'master' into peer-scoring-service
* Merge branch 'master' into peer-scoring-service
* adds scorer_test
* gazelle
* updates bad response default penalty
* more comments
* Merge branch 'master' into peer-scoring-service
* Merge branch 'master' into peer-scoring-service
* Merge branch 'master' into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* introduces peerdatastore into status
* makes sure that commong peer data store is used
* Merge branch 'peer-scoring-service' of github.com:prysmaticlabs/prysm into peer-scoring-service
* linter
* gazelle
* updates tests
* Merge branch 'master' into peer-scoring-service
* fixes tests
* Nishant's suggestions
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge refs/heads/master into peer-scoring-service
* Merge branch 'master' into peer-scoring-service
* gofmt
* Nishant's suggestion to use isBadPeer
* Merge refs/heads/master into peer-scoring-service
2020-07-20 15:12:59 +00:00
Victor Farazdagi
22141db319 Applies assertion funcs to validator/accounts tests (#6653)
* Applies assertion funcs to validator/accounts tests
* Applies assertion funcs to validator/accounts tests
2020-07-20 10:56:45 +00:00
Victor Farazdagi
10d3275638 Applies assertion funcs to rpc tests (#6641)
* applies assertion funcs to beacon-chain/rpc tests
* Merge branch 'master' into rpc-apply-testutils-assertions
* applies assertion funcs to beacon-chain/rpc/beacon tests
* Merge branch 'master' into rpc-apply-testutils-assertions
* applies assertion funcs to beacon-chain/rpc/debug tests
* applies assertion funcs to beacon-chain/rpc/validator tests
* Merge branch 'master' into rpc-apply-testutils-assertions
* Merge refs/heads/master into rpc-apply-testutils-assertions
2020-07-20 02:15:51 +00:00
Victor Farazdagi
1d0fe105fc Extends assertions to accept fmt params (#6645)
* Extends assertions to accept fmt params
2020-07-20 01:36:28 +00:00
terence tsao
0544dd1f8e Applies assertion funcs to shared tests (#6643)
* cmd tests
* deposit util tests
* feature config tests
* hashutil tests
* htr util tests
* interop tests
* ip util tests
2020-07-19 21:08:29 +00:00
Preston Van Loon
b60a965981 ProcessAttestations: Add requirement that inclusion distance is not zero (#6642)
* Add requirement that inclusion distance is not zero, add regression test
* fix test input data
* Merge refs/heads/master into fix-panic
* Merge refs/heads/master into fix-panic
2020-07-19 16:38:45 +00:00
terence tsao
38c8393e52 Revert "Fixes issue with vals order in assert.Equal" (#6640)
* Revert "Fixes issue with vals order in assert.Equal (#6631)"

This reverts commit d535cb95d8.
* Merge branch 'master' into revert-6631-assertions-less-assuming-error-msg
2020-07-19 04:45:04 +00:00
Victor Farazdagi
568238009e Extracts peer data store in p2p/peers status (#6639)
* introduces peer data store to p2p/peers
* Merge refs/heads/master into p2p-extract-data-store
* Merge refs/heads/master into p2p-extract-data-store
* refactores status service
* Merge branch 'p2p-extract-data-store' of github.com:prysmaticlabs/prysm into p2p-extract-data-store
* updates tests
* gofmt
* rever decay test
2020-07-19 03:45:08 +00:00
Preston Van Loon
c419e4ed8f Improved cold state checkpoints: migrate database index and usage (#6461)
* Add database migrations, still need to update the API usage...
* gofmt goimports
* progress
* Merge branch 'master' of github.com:prysmaticlabs/prysm into index-migration
* use slot instead of index
* rename LastArchivedIndex to LastArchivedSlot
* rename LastArchivedIndexRoot to LastArchivedRoot
* remove unused HighestSlotStates method
* deprecate old key, include in migration
* deprecate old key, include in migration
* remove blocks index in migration
* rename bucket variable
* fix code to pass tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into index-migration
* gofmt, goimports
* fix
* Add state slot index
* progress
* lint
* fix build
* Merge branch 'master' of github.com:prysmaticlabs/prysm into index-migration
* kafka
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* remove SaveArchivedPointRoot, a few other big changes
* Merge branch 'index-migration' of github.com:prysmaticlabs/prysm into index-migration
* fix tests and lint
* lint again
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* block migration, some renaming
* gaz, gofmt
* add tests
* change index to uint bytes
* Merge branch 'index-migration' of github.com:prysmaticlabs/prysm into index-migration
* rm method notes
* stop if the bucket doesn't exist
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* @rauljordan pr feedback
* Simplify
* Merge refs/heads/master into index-migration
* Remove unused method, add roundtrip test
* gofmt
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge refs/heads/master into index-migration
* Merge branch 'master' of github.com:prysmaticlabs/prysm into index-migration
2020-07-18 18:05:04 +00:00
terence tsao
d53539499c Applies assertion funcs to shared tests (part 1) (#6626)
* Update kv aggregated_test.go
* Update block_test.go
* Update forkchoice_test.go
* Update unaggregated_test.go
* Update prepare_forkchoice_test.go
* Update prune_expired_test.go
* Update atts service_test.go
* Update service_attester_test.go
* Update service_proposer_test.go
* Upate exit service_test.go
* Gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Move averageBalance from log.go to info.go
* Move avg balance from log.go to info.go
* Add info test
* Remove unused logEpochData in log.go
* Gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* aggregation tests
* attestation util tests
* bench util tests
* block util tests
* herumi tests
* bytesutil tests
* 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
* Update shared/aggregation/attestations/attestations_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
* Merge branch 'master' of github.com:prysmaticlabs/prysm into testutil-shared
* Fixed ordering
* Merge branch 'testutil-shared' of github.com:prysmaticlabs/prysm into testutil-shared
* Update shared/aggregation/attestations/attestations_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
* Update shared/bytesutil/bytes_test.go

Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-07-18 16:31:42 +00:00
Victor Farazdagi
d535cb95d8 Fixes issue with vals order in assert.Equal (#6631)
* fixes issue with vals order in assert.Equal
2020-07-18 11:14:50 +00:00
Victor Farazdagi
7ba500c417 Applies assertion funcs to state tests (#6623)
* applies assertion funcs to beacon-chain/state tests
* applies assertion funcs to beacon-chain/state/stategen tests
* applies assertion funcs to beacon-chain/state/stateutil tests
* gazelle
* Merge refs/heads/master into state-apply-testutils-assertions
* Merge refs/heads/master into state-apply-testutils-assertions
* Merge refs/heads/master into state-apply-testutils-assertions
2020-07-18 07:56:48 +00:00
Preston Van Loon
c573306621 Check for array out of bounds when calculating proposer delta -- follow up (#6630)
* failing test
* fix
2020-07-18 06:39:43 +00:00
Preston Van Loon
5336a167af Check for array out of bounds when calculating proposer delta (#6629)
* Check for array out of bounds when calculating proposer delta
* Merge refs/heads/master into proposer-delta-bug
2020-07-18 04:31:03 +00:00
Preston Van Loon
0e4cb68249 Add regression test found by fuzzer (#6628)
* Add regression test found by fuzzer
2020-07-18 03:47:03 +00:00
Nishant Das
cc3c3a0c54 QSP 29: Add Rate Limiter For All Topics (#6606)
* initial commit
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into rateLimiter
* finally
* add mutex
* rate limiter for all rpc reqs
* remove recursive readlocks
* spelling
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* fix all tests
* fix all tests
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
* Merge refs/heads/master into rateLimiter
2020-07-17 08:58:51 +00:00
Raul Jordan
9ad6277852 Accounts V2: Create Wallet Non-Interactively + Add Test Coverage (#6611)
* create wallet noninteractively
* tests for wallet create
* kapol feedback
* Merge refs/heads/master into create-wallet-tests
* Merge refs/heads/master into create-wallet-tests
2020-07-17 08:21:16 +00:00
terence tsao
ebd05fba01 Improve test coverage info.go (#6618)
* Update kv aggregated_test.go
* Update block_test.go
* Update forkchoice_test.go
* Update unaggregated_test.go
* Update prepare_forkchoice_test.go
* Update prune_expired_test.go
* Update atts service_test.go
* Update service_attester_test.go
* Update service_proposer_test.go
* Upate exit service_test.go
* Gaz
* Merge branch 'master' of github.com:prysmaticlabs/prysm
* Move averageBalance from log.go to info.go
* Move avg balance from log.go to info.go
* Add info test
* Remove unused logEpochData in log.go
* Gaz
* Merge branch 'master' into info-cov
* gaz
* Merge refs/heads/master into info-cov
2020-07-16 22:44:43 +00:00
rkapka
eb0d70814a Fixed nil pointer error in DepositCache (#6596) 2020-07-16 14:48:36 -07:00
rkapka
77607c6fdb Applies assertion funcs to cache tests (#6617)
* testutils for cache
* Merge branch 'master' into cache-test-refactor
* removed some empty lines
* Merge branch 'origin-master' into cache-test-refactor
* Merge remote-tracking branch 'rkapka/cache-test-refactor' into cache-test-refactor
* revert package names
2020-07-16 19:34:08 +00:00
Nishant Das
cf2bbec6a8 Use Faster Hash Function (#6616)
* change to proto hash

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-16 10:19:14 -05:00
terence tsao
69a2dc2716 Improve test coverage receive_block.go (#6613)
* Update kv aggregated_test.go
* Update block_test.go
* Update forkchoice_test.go
* Update unaggregated_test.go
* Update prepare_forkchoice_test.go
* Update prune_expired_test.go
* Update atts service_test.go
* Update service_attester_test.go
* Update service_proposer_test.go
* Upate exit service_test.go
* Gaz
* TestService_ReceiveBlockInitialSync
* TestService_ReceiveBlockBatch
* TestService_HasInitSyncBlock
* Merge branch 'master' of github.com:prysmaticlabs/prysm into rcv-blk-cov
* Merge branch 'master' of github.com:prysmaticlabs/prysm into rcv-blk-cov
* Merge branch 'rcv-blk-cov' of github.com:prysmaticlabs/prysm into rcv-blk-cov
* Gaz
* Merge refs/heads/master into rcv-blk-cov
* Merge refs/heads/master into rcv-blk-cov
* Merge refs/heads/master into rcv-blk-cov
* Merge refs/heads/master into rcv-blk-cov
2020-07-16 13:34:34 +00:00
Raul Jordan
d897640625 Add YAML Struct Tag to Eth1FollowDistance Parameter (#6612)
* add yaml struct tag to eth1 follow distance
* more config values missing yaml tags
* Merge refs/heads/master into follow-distance-struct-tag
* Merge refs/heads/master into follow-distance-struct-tag
* Merge refs/heads/master into follow-distance-struct-tag
2020-07-16 13:04:59 +00:00
Victor Farazdagi
deb025f57c Applies assertion funcs to blockchain tests (#6605)
* applies assertion funcs to blockchain tests
* Merge branch 'master' into blockchain-apply-testutils-assertions
* gofmt
* Merge refs/heads/master into blockchain-apply-testutils-assertions
* Merge refs/heads/master into blockchain-apply-testutils-assertions
* Merge refs/heads/master into blockchain-apply-testutils-assertions
* Merge refs/heads/master into blockchain-apply-testutils-assertions
* Merge refs/heads/master into blockchain-apply-testutils-assertions
2020-07-16 12:11:39 +00:00
Nishant Das
f6756bb591 QSP 23: Prune Peers From Peer Handler (#6614)
* checkpoint
* Merge refs/heads/master into prunePeers
2020-07-16 10:09:51 +00:00
Raul Jordan
df73851749 Accounts Revamp: Wallet Edit-Config (#6607)
* edit remote config
* gets messed up when writing to file again
* proper editing
* noninteractive mode
* test for edit wallet
* Merge branch 'master' into edit-wallet
* wallet edit test done
* imports
* Merge refs/heads/master into edit-wallet
* Merge refs/heads/master into edit-wallet
2020-07-16 05:08:16 +00:00
Ivan Martinez
fbeba94a92 Change accounts-v2 import and export to be non-interactive (#6609)
* Change import and export to be non-interactive
* Fix
* fix lint
* Merge branch 'master' into make-export-import-nonint
* Comments
* Merge branch 'make-export-import-nonint' of github.com:prysmaticlabs/prysm into make-export-import-nonint
* Merge refs/heads/master into make-export-import-nonint
2020-07-15 23:00:00 +00:00
Victor Farazdagi
a0e5754464 Resolves possible import cycle in testutils assertions (#6610)
* resolves possible import cycle in testutils assertions
* gazelle
* linter
* linter
2020-07-15 20:10:54 +00:00
terence tsao
c309ba6a10 Applies assertion funcs to operation tests (#6608)
* Update kv aggregated_test.go
* Update block_test.go
* Update forkchoice_test.go
* Update unaggregated_test.go
* Update prepare_forkchoice_test.go
* Update prune_expired_test.go
* Update atts service_test.go
* Update service_attester_test.go
* Update service_proposer_test.go
* Upate exit service_test.go
* Gaz
2020-07-15 18:37:51 +00:00
Victor Farazdagi
c2615168d9 Applies assertion funcs to sync tests (#6603)
* applies assertion funcs to sync/initial-sync tests
* applies assertion funcs to sync/initial-sync tests
* gazelle
* Merge branch 'master' into sync-apply-testutils-assertions
* gazelle
* applies assertion funcs to sync/initial-sync tests
* applies assertion funcs to sync/initial-sync tests
* applies assertion funcs to sync/initial-sync tests
* applies assertion funcs to sync/initial-sync tests
* applies assertion funcs to sync/initial-sync tests
* Merge branch 'master' into sync-apply-testutils-assertions
2020-07-15 04:41:11 +00:00
Raul Jordan
f12f75224e Accounts V2: Create Wallet via CLI (#6543)
* begin on the proto definitions

* define remote signer service protos

* basic implementation

* remote keymanager docs

* finalize remote client doc

* amend response

* fix proto defs

* test new and begin test sign

* test sign done

* remote oneof

* rename

* fix build

* viz

* Update validator/keymanager/v2/remote/remote_test.go

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

* Update validator/accounts/v2/wallet.go

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

* fmt

* move the input check to accounts new

* begin on requesting cli input for remote keymanager config

* move the input check to accounts new

* begin on requesting cli input for remote keymanager config

* define wallet v2

* create wallet most logic done

* init remote wallet

* create wallet moving nicely

* ensure wallet create works

* reenable import export list

* further refactor

* improve handling of input wallet dir

* add all validation to cert path checks

* lint

* list test

* new wallet lint

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
2020-07-14 23:05:21 -05:00
terence tsao
fe14c5086a Fix duplicated selectV1Keymanager (#6604)
* Fix duplicated selectV1Keymanager
2020-07-15 01:05:33 +00:00
Ivan Martinez
d7bcea7906 Allow creating new accounts to be non-interactive (#6602)
* Allow accounts to be made non-interactively
* Merge branch 'master' of github.com:prysmaticlabs/prysm into make-accounts-noninteractive
* Update validator/node/node.go
* Update validator/accounts/v2/list.go
2020-07-14 23:00:58 +00:00
terence tsao
eef9a760ec Fix inconsistent pubkey formatting in logs (#6600)
* Use Trunc for pub key
* Gaz
* Merge refs/heads/master into fix-pub-key
2020-07-14 20:37:01 +00:00
Ivan Martinez
5278b75c02 E2E Improvements (#6587)
* Change long-running e2e to run minimally
* Merge branch 'master' into e2e-config-change
* Remove deposits flag
* Merge branch 'e2e-config-change' of github.com:prysmaticlabs/prysm into e2e-config-change
* Merge branch 'master' of github.com:prysmaticlabs/prysm into e2e-config-change
* Reduce secondsperslot
* Add todo
* Merge branch 'master' of github.com:prysmaticlabs/prysm into e2e-config-change
* Merge refs/heads/master into e2e-config-change
* Merge refs/heads/master into e2e-config-change
* Merge refs/heads/master into e2e-config-change
* Merge refs/heads/master into e2e-config-change
* Merge refs/heads/master into e2e-config-change
* Merge refs/heads/master into e2e-config-change
2020-07-14 18:08:17 +00:00
Victor Farazdagi
d9fd2521af Applies assertion funcs to p2p tests (#6597)
* applies assertion funcs to p2p/encoder tests
* applies assertion funcs to p2p/peers tests
* addr_factory_test + broadcaster_test updated
* connection_gater_test updated
* applies assertion funcs to p2p/service tests
* Merge branch 'master' into p2p-apply-testutils-assertions
* minor fixes
* Merge branch 'master' into p2p-apply-testutils-assertions
* Merge refs/heads/master into p2p-apply-testutils-assertions
2020-07-14 16:51:39 +00:00
terence tsao
ea32af7bf7 Update justified point for batch sync (#6594)
* Update justified points
* Add the same check to on block init sync
* Add comments
* Add test
* Gaz
* Merge branch 'master' into fix-batch-sync
* Merge refs/heads/master into fix-batch-sync
2020-07-14 16:20:25 +00:00
terence tsao
8fda48409c Remove batch blocks save at getAttPreState (#6584)
* Check if block exists in cache
* Consider init sync blocks
* Fixed test
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
* Merge refs/heads/master into get-block
2020-07-14 15:46:00 +00:00
Shay Zluf
e0c803abfc Fast list validators (#6580)
* Fast list validators
* fix tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fast_list_validators
* add small test
* Merge branch 'master' into fast_list_validators
* remove unneeded fatcher
* Merge branch 'fast_list_validators' of github.com:prysmaticlabs/prysm into fast_list_validators
* nishant feedback
* package name
2020-07-14 12:21:55 +00:00
Preston Van Loon
b099cab9b1 automaxprocs: Log error to DEBUG instead of panic (#6592)
* Log error to DEBUG instead of panic. Fixes #6591
* Merge branch 'master' into fix-6591
2020-07-14 01:51:07 +00:00
Ivan Martinez
52e9155df3 Change validator accounts-v2 to validator wallet-v2 accounts (#6589)
* Change `validator accounts-v2` to `validator wallet-v2 accounts-v2

* Change to accounts

* Fix cmd

* Rename cmd.go to cmd_accounts.go
2020-07-13 19:58:06 -05:00
Preston Van Loon
774b4b7eef SubmitAggregateAndProof now prefers its own validator attestations (#6566)
* SubmitAggregateAndProof now prefers its own validator attestations
* only do aggregate bits count comparsion when best also contains the validator index
* gofmt
* better test
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* @terencechain feedback
* Merge refs/heads/master into prefer-own-attestation
* update comment
* Merge branch 'prefer-own-attestation' of github.com:prysmaticlabs/prysm into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
* Merge refs/heads/master into prefer-own-attestation
2020-07-13 22:02:01 +00:00
Ivan Martinez
cd2ea868ff Direct Keymanager: Add Export and Import commands (#6528)
* add in configs
* ask for enable accounts v2
* begin integration of v2 keymanager
* refactor wallet opening
* include significant refactoring of how opening a wallet works, making it easy to include at runtime
* ensure build with keymanager v2
* further improving runtime integration
* default pass paths
* finally running v2 at runtime
* import spacing
* Merge branch 'master' into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Get started on export and import commands
* Work more on import
* Complete functionality
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-import
* Undo
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-import
* cleanup
* Extract code to functions
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-import
* Add comments
* Fix ocmments
* Improvements
* fix
* Merge branch 'master' of github.com:prysmaticlabs/prysm into accounts-import
* Remove GetSigningKeyForAccount
* Progress
* Fix build
* Fix name
* Merge branch 'master' into accounts-import
* Add logging
* Merge branch 'accounts-import' of github.com:prysmaticlabs/prysm into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
* Merge refs/heads/master into accounts-import
2020-07-13 21:37:18 +00:00
terence tsao
2bbae15194 Handle roughtime response error (#6586)
* Handle roughtime response error
* Update shared/roughtime/roughtime.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Merge branch 'master' into fix-roughtime-logs
* Update shared/roughtime/roughtime.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Merge refs/heads/master into fix-roughtime-logs
* Merge refs/heads/master into fix-roughtime-logs
* Merge refs/heads/master into fix-roughtime-logs
2020-07-13 21:00:43 +00:00
terence tsao
18f28e2840 VerifyBlkDescendant - fixed a nil return bug and added a test (#6553)
* Refactor verifyBlkDescendant to be public and omit the slot argument, which was only used for error messages
* impl in mock
* gofmt
* Merge refs/heads/master into refactor-verifyBlkDescendant-signature
* Better errors
* Tests. Yay!
* Comments
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Fixed receive blck test
* Merge branch 'test-blk-des' of github.com:prysmaticlabs/prysm into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Ensure finalized root not zeros
* Merge branch 'test-blk-des' of github.com:prysmaticlabs/prysm into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
* Ensure non zero hashes when compare
* Merge branch 'test-blk-des' of github.com:prysmaticlabs/prysm into test-blk-des
* Merge refs/heads/master into test-blk-des
* Merge refs/heads/master into test-blk-des
2020-07-13 20:14:36 +00:00
Nishant Das
27577bc324 QSP 32: Add Appropriate Stream Deadlines for RPC Requests (#6583)
* add no deadlines
* Merge branch 'master' into fixDeadlines
* nogo
* Merge refs/heads/master into fixDeadlines
* Merge refs/heads/master into fixDeadlines
2020-07-13 19:40:12 +00:00
Nishant Das
79fbaaea0b QSP18: Add Varint Header Validation (#6577)
* add header validation

* Update beacon-chain/p2p/encoder/varint_test.go

* Update beacon-chain/p2p/encoder/varint_test.go

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-07-13 14:02:03 -05:00
Victor Farazdagi
d1e754f011 Fixes display issue in testutils/assert (#6585)
* fixes minor display issue in testutils/assert
2020-07-13 17:20:18 +00:00
Victor Farazdagi
77d1a6c698 Adds testutils/assert and testutils/require (#6563)
* testutils/assert

* adds assertion tb mock

* testutil/require

* gazelle

* comment public types

* set TestOnly attribute

* fixes package name

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-13 10:19:52 -05:00
Nishant Das
f2b4f91419 save blocks (#6578) 2020-07-13 06:33:45 -07:00
Justin
ec800bac7c Remove redundant check in exit.go (#6559)
* Remove redundant check in exit.go

The check `exit.Exit.ValidatorIndex >= uint64(beaconState.NumValidators())` is done in `beaconState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)`.
* Merge branch 'master' into patch-1
* Merge branch 'master' into patch-1
* Merge branch 'master' into patch-1
* Merge branch 'master' into patch-1
* Merge branch 'master' into patch-1
2020-07-13 09:36:40 +00:00
Nishant Das
63cb99b359 add logs (#6575) 2020-07-12 22:36:03 -07:00
Nishant Das
b5bd1260d0 Clean Up P2P Service (#6574)
* clean up
* clean up
* gaz
* preston's review
* preston's review
* Merge refs/heads/master into CleanUpP2P
2020-07-13 04:16:24 +00:00
terence tsao
62df4995e6 Clean up block chain pkg initial sync (#6562) 2020-07-12 20:44:06 -07:00
Victor Farazdagi
c35bdf2649 Refactors calls to deprecated libp2p methods (#6554)
* refactors calls to deprecated IDB58Decode()
* Merge branch 'master' into p2p-refactor-deprecated
* updated packages
* gazelle
* mod tidy
* refactors publish()/subscribe() deprecated methods
* gofmt
* test update join/leave topic methods
* re-arrange imports
* Merge branch 'master' into p2p-refactor-deprecated
* Merge refs/heads/master into p2p-refactor-deprecated
2020-07-13 02:28:40 +00:00
Nishant Das
d4c3546434 Validate RPC Topics Before Sending Requests (#6558)
* clean up

* fix panic

* add test mapping

* add schema version change

* fix test

* fix another test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-13 09:20:53 +08:00
Ivan Martinez
10c0d5b569 Remove unused functions in validator DB (#6557)
* Remove unused functions in validator DB
* Iface
* Merge branch 'master' into reomve-unused-val-db
* Merge branch 'master' into reomve-unused-val-db
* Merge refs/heads/master into reomve-unused-val-db
2020-07-11 17:23:30 +00:00
Ivan Martinez
18c00ab25d Add BoltTimeout to IO config (#6555)
* Make bolt timeout a config value
* Merge refs/heads/master into best-practices0timeout
* Merge refs/heads/master into best-practices0timeout
* Merge refs/heads/master into best-practices0timeout
2020-07-11 16:43:26 +00:00
Nishant Das
b82defddb2 add timeouts (#6560) 2020-07-11 08:18:25 -07:00
Preston Van Loon
fa85d93a19 Verify roughtime results before accepting time offset (#6556)
* Verify roughtime results before accepting time offset
2020-07-11 04:42:26 +00:00
Preston Van Loon
1f35384578 Reject a block which its parent is not part of the finalized chain (#6549)
* Reject a block which its parent is not part of the finalized chain
* Refactor verifyBlkDescendant to be public and omit the slot argument, which was only used for error messages
* Merge branch 'refactor-verifyBlkDescendant-signature' into reject-bad-block
* fix
* impl in mock
* impl in mock
* gofmt
* Merge refs/heads/master into refactor-verifyBlkDescendant-signature
* Merge branch 'refactor-verifyBlkDescendant-signature' into reject-bad-block
* fix test
* add test
* Merge branch 'refactor-verifyBlkDescendant-signature' into reject-bad-block
* gofmt
* Merge branch 'master' of github.com:prysmaticlabs/prysm into reject-bad-block
* move up in the validation pipeline, @terencechain offline feedback
* Merge refs/heads/master into reject-bad-block
2020-07-11 03:57:42 +00:00
Preston Van Loon
c9ca5857f8 Avoid automaxprocs default logger to printf (#6524)
* Avoid automaxprocs default logger to printf
* Merge branch 'master' into maxprocs
* gofmt, goimports
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* gazelle for docker images
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
* fix docker
* Merge refs/heads/master into maxprocs
* Merge refs/heads/master into maxprocs
2020-07-11 00:57:43 +00:00
Preston Van Loon
6c7965e82a Refactor verifyBlkDescendant to be public in chainservice API (#6552)
* Refactor verifyBlkDescendant to be public and omit the slot argument, which was only used for error messages
* impl in mock
* gofmt
* Merge refs/heads/master into refactor-verifyBlkDescendant-signature
* fix test
2020-07-11 00:16:52 +00:00
Preston Van Loon
29317ca8da Attestation cache: check bitlist length before checking contains (#6551)
* Attestation cache: check bitlist length before checking contains
2020-07-10 21:05:03 +00:00
Preston Van Loon
dbc9686d15 Add roughtime offset histogram metric, log on large offsets (#6546)
* Add roughtime_offset_nsec metric. Log a warning if offset is greater than 2 seconds
* gofmt
* use math.abs, add help text
* gofmt
2020-07-10 17:07:49 +00:00
Nishant Das
cc8b3e349d Save Boundary States (#6542) 2020-07-10 09:00:41 -07:00
Raul Jordan
2c9474ab7f Remote Keymanager: Proto Definitions and Basic Client Implementation (#6526)
* begin on the proto definitions
* define remote signer service protos
* basic implementation
* remote keymanager docs
* finalize remote client doc
* amend response
* fix proto defs
* test new and begin test sign
* test sign done
* Merge branch 'master' into remote-keymanager-v2
* remote oneof
* rename
* Merge branch 'remote-keymanager-v2' of github.com:prysmaticlabs/prysm into remote-keymanager-v2
* fix build
* Merge refs/heads/master into remote-keymanager-v2
* viz
* Merge branch 'remote-keymanager-v2' of github.com:prysmaticlabs/prysm into remote-keymanager-v2
* Merge refs/heads/master into remote-keymanager-v2
* Merge refs/heads/master into remote-keymanager-v2
* Update validator/keymanager/v2/remote/remote_test.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
* Update validator/accounts/v2/wallet.go

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
* fmt
2020-07-10 05:49:56 +00:00
terence tsao
ac79819077 Fix genesis validator count (#6540)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-09 19:54:24 -05:00
terence tsao
d54cefbe42 Part 1 of blockchain pkg clean up (#6537)
* Fix span names

* Clean up on block func

* Add updateFinalized helper

* Deprecate ReceiveBlockNoPubsub for ReceiveBlock

* Proposer to broadcast block

* Update migrate interface

* Replace ReceiveBlock for all

* Go fmt
2020-07-09 18:50:48 -05:00
rkapka
f7088e037c Finalized deposits cache (#6391)
* Renamed beforeBlk to untilBlk
* finalized deposits cache logic
* Merge branch 'master' into deposit-trie-cache

# Conflicts:
#	beacon-chain/blockchain/process_block.go
* simplified returning of finalized deposits
* added comment to FinalizedDeposits struct
* fixes after code review
* Merge branch 'master' into deposit-trie-cache
* fixed variable declaration
* renamed deposit cache test file
* fixed type casting
* compilation error fix
* deposit cache tests
* proposer test
* Merge branch 'master' into deposit-trie-cache
* added missing methods to interop beacon-chain service
* gofmt
* Merge branch 'master' into deposit-trie-cache
* gazelle
* cache deposit with eth1DepositIndex
* Merge branch 'master' into deposit-trie-cache
* fixed MerkleTrieIndex name
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
* code review adjustments
* feature flag
* Merge branch 'master' into deposit-trie-cache

# Conflicts:
#	beacon-chain/cache/depositcache/pending_deposits.go
#	shared/featureconfig/config.go
#	shared/featureconfig/flags.go
* merge fix
* gazelle
* Merge branch 'master' into deposit-trie-cache
* return a copy of deposits trie from the cache
* move more logic under feature flag
* Merge branch 'master' into deposit-trie-cache
* added missing beacon chain flag
* Merge branch 'master' into deposit-trie-cache
* use helper function for trie copying
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
* Merge branch 'master' into deposit-trie-cache
2020-07-09 20:24:40 +00:00
Ivan Martinez
b052ab7087 Make E2E less flaky (#6536) 2020-07-09 14:08:21 -05:00
Ivan Martinez
322998f7f1 Move subnet topics to global vars (#6525)
* Deduplicate subnet topic definitions
* Move topics to global file
* Gaz
* Merge branch 'master' into move-topics
* Fix
* Merge refs/heads/master into move-topics
* Bazel
* Merge branch 'move-topics' of github.com:prysmaticlabs/prysm into move-topics
* Fix tests
* Fix
* Undo e2e changes
* Revert "Undo e2e changes"

This reverts commit 3037bb3590.
* Fix
* Fix
* Merge refs/heads/master into move-topics
* Merge refs/heads/master into move-topics
* Merge refs/heads/master into move-topics
* Comments
* Merge refs/heads/master into move-topics
* Merge refs/heads/master into move-topics
2020-07-09 17:38:15 +00:00
terence tsao
47cbfbf437 Remove participation link when list accounts (#6535)
* Remove url
* Merge refs/heads/master into rm-link
2020-07-09 16:50:19 +00:00
Raul Jordan
15d660d8eb Direct Keymanager: Proper Keystore.json Formatting (#6527)
* ensure keystore file has all fields
* fix tests
* fix build
* Merge branch 'master' into full-keystore-json
* define wallet.CanUnlockAccounts() to determine secret keys cache
initialization
* Merge branch 'full-keystore-json' of github.com:prysmaticlabs/prysm into full-keystore-json
* add can unlock accounts items
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
2020-07-09 16:24:06 +00:00
Raul Jordan
e3de674c77 Direct Keymanager: Proper Keystore.json Formatting (#6527)
* ensure keystore file has all fields
* fix tests
* fix build
* Merge branch 'master' into full-keystore-json
* define wallet.CanUnlockAccounts() to determine secret keys cache
initialization
* Merge branch 'full-keystore-json' of github.com:prysmaticlabs/prysm into full-keystore-json
* add can unlock accounts items
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
* Merge refs/heads/master into full-keystore-json
2020-07-09 16:23:53 +00:00
Preston Van Loon
fd80f73286 Improve make() capacity allocations (#6517)
* attestationutil.AttestingIndices: Minor improvement on indices array allocation
* progress
* more progress on makes
* progress
* more progress
* Merge branch 'master' of github.com:prysmaticlabs/prysm into memory1
* gaz
* fmt and imports
* Merge branch 'master' into memory2
* Min()
* remove spaces
* Merge branch 'master' of github.com:prysmaticlabs/prysm into memory2
* revert beacon-chain/operations/attestations/kv/block.go
* partially revert beacon-chain/operations/attestations/kv/aggregated.go
* Merge branch 'master' into memory2
* Merge branch 'master' into memory2
2020-07-09 15:50:58 +00:00
Nishant Das
c804347fc4 add fix and test (#6533)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-09 09:46:35 -05:00
Jim McDonald
b00c235586 Add separate permission for directories. (#6532) 2020-07-09 22:05:43 +08:00
Preston Van Loon
c2deab8948 State: use a constant for field count (#6513)
* State: use a constant for field count
* one more field count for alloc
* one more field count for alloc
* Merge branch 'master' into field-const-21
* Merge branch 'master' into field-const-21
* Merge branch 'master' into field-const-21
* Merge branch 'master' into field-const-21
2020-07-09 03:37:08 +00:00
terence tsao
8da0246702 Close buf writer in event of an error (#6523)
* Close buf writer in event of an error
* Merge refs/heads/master into close-bufwriter
* Merge refs/heads/master into close-bufwriter
2020-07-08 20:03:03 +00:00
Raul Jordan
132ad5beb8 Implement Accounts-v2 List: Direct Keymanager (#6510)
* begin list accounts impl
* colorize
* show deposit data
* separate responsibility
* comprehensive test for list complete
* gaz viz
* print account creation timestamp
* handle errs
* ask for wallet and pass dir
* Merge refs/heads/master into implement-v2-list
2020-07-08 19:21:54 +00:00
Ivan Martinez
ddf494f7b7 Use same permissions for all files in Prysm (#6522)
* Unify all perm prysm wide

* Gaz

* Imports
2020-07-08 12:30:22 -05:00
Victor Farazdagi
af4dfd4c36 Tiny optimization in state refs lock/unlock (#6520)
* tiny optimization in state refs count
2020-07-08 12:53:36 +00:00
Preston Van Loon
f2f2677070 attestationutil.AttestingIndices: Minor improvement on indices array allocation (#6508)
* attestationutil.AttestingIndices: Minor improvement on indices array allocation
* Merge branch 'master' of github.com:prysmaticlabs/prysm into HEAD
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
* Merge refs/heads/master into memory1
2020-07-08 09:57:50 +00:00
Preston Van Loon
a279f18461 Change from int64 to int for all flags so they load properly from config file. (#6498)
* Change from int64 to int for monitoring port so that the monitoring port is correctly ready from config file.
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
* replace all other usages of int64 flag. @nisdas feedback
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' of github.com:prysmaticlabs/prysm into fix-monitoring-port
* revert tools/sendDepositTx
* fix build
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
* Merge branch 'master' into fix-monitoring-port
2020-07-08 08:21:06 +00:00
Preston Van Loon
c1ccadae55 Delete unused helpers.AttestingIndices (#6509)
* Delete unused helpers.AttestingIndices
* Merge branch 'master' into rm-AttestingIndices
* Merge branch 'master' into rm-AttestingIndices
* Merge branch 'master' into rm-AttestingIndices
* Merge branch 'master' into rm-AttestingIndices
2020-07-08 07:30:29 +00:00
Preston Van Loon
a02553815f Allocate the appropriate memory for retrieveIndicesFromBitfield (#6507)
* Allocate the appropriate memory for retrieveIndicesFromBitfield
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
* Merge refs/heads/master into memory0
2020-07-08 05:47:26 +00:00
Raul Jordan
fd9003f822 Integrate Accounts v2 Keymanager Into Validator Client (#6489)
* add in configs
* ask for enable accounts v2
* begin integration of v2 keymanager
* refactor wallet opening
* include significant refactoring of how opening a wallet works, making it easy to include at runtime
* ensure build with keymanager v2
* further improving runtime integration
* default pass paths
* finally running v2 at runtime
* import spacing
* Merge branch 'master' into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* confs
* rem e2e val flag
* Merge branch 'master' into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
* Merge refs/heads/master into v2-accounts-feature
2020-07-08 05:01:09 +00:00
terence tsao
fe13f1f856 Add init-sync-verbose feature flag (#6515)
* Add flag
* Use flag
* Merge refs/heads/master into init-sync-verbose
* Merge refs/heads/master into init-sync-verbose
* Merge refs/heads/master into init-sync-verbose
* Merge refs/heads/master into init-sync-verbose
* Merge refs/heads/master into init-sync-verbose
2020-07-08 04:19:58 +00:00
Nishant Das
074e3c9aa7 Use Custom Block Hashing Method (#6501)
* blockroot
* gaz
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
* Merge refs/heads/master into useCustomMethod
2020-07-08 03:53:16 +00:00
terence tsao
d42d685f78 Update verifyBlkPreState to verify only (#6506)
* Verify should not return the state
* Update tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into refactor
* Sync with master
* Merge refs/heads/master into refactor
* Fixed error msgs. Thanks @rauljordan
* Merge branch 'master' of github.com:prysmaticlabs/prysm into refactor
* Merge branch 'refactor' of github.com:prysmaticlabs/prysm into refactor
* Merge refs/heads/master into refactor
* Merge refs/heads/master into refactor
* Merge refs/heads/master into refactor
2020-07-08 02:54:55 +00:00
Preston Van Loon
1067800430 p2p.AddConnectionHandler: Remove unused arg for goodbyeFunc (#6511)
* p2p.AddConnectionHandler: Remove unused arg for goodbyeFunc
* accidental rename reqFunc
* update test
* Merge branch 'master' into rm-unused-param
* Merge branch 'master' into rm-unused-param
2020-07-08 02:04:15 +00:00
terence tsao
d53ab16004 Move skip-regen-historical-states to deprecated (#6512)
* Remove unused test
* Move flag to be deprecated
* Remove usages
* Update BUILD.bazel
* Merge refs/heads/master into rm-skip-stategen-usages
2020-07-08 00:15:45 +00:00
Preston Van Loon
90b8b76ae8 Remove unused EpochAttestationsRoot method (#6514)
* Remove unused EpochAttestationsRoot method
2020-07-07 23:39:11 +00:00
dv8silencer
c77296ff82 Show overall validator results in addition to epoch specific results (#6492)
* Add aggregate stats struct to validator struct.  Log aggregate voting summary
from beginning of node startup.
* Refactoring out to function UpdateLogAggregateStats which updates and logs aggregate statistics
* Changes to spelling.  More refactoring so that the rest of aggregate stats are moved to UpdateLogAggregateStats
* Bugfix - moved startBalance initialization out of if.
* Remove a print debug.  Spelling adjustment.
* Minor refactoring/grammar changes
* Renaming variables for consistency.
* Address linter feedback:  omit 2nd value from range over map as values were not being used.
* Address feedback from PR re comments.

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
* Addressing feedback from terencechain in PR. (name changes)
* Addressing feedback from terencechain in PR.
* Create test for UpdateLogAggregateStats()
* Changed comment regarding "numberOfEpochs" log
* go fmt metrics_test.go
* bazel run //:gazelle -- fix
* fix typos
* Improved the code to detect the last iteration of the range responses loop
* Merge branch 'master' into tempIssue4987
* For both previous Epoch and total runtime statistics, do not count non-included attestations for "correctly" statistics.
* Update wording in since-launch logging

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
* Store first logged epoch in startEpoch and appropriately adjust calculations.  Initialize startEpoch to ^uint64(0).
* Merge branch 'master' into tempIssue4987
* Update validator/client/metrics.go
* Update validator/client/metrics.go
* Update validator/client/validator.go
* Update validator/client/metrics_test.go
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
* Merge branch 'master' into tempIssue4987
2020-07-07 19:23:56 +00:00
Shay Zluf
87c18d4e0d Slasher readiness status response (#6504)
* Slasher readiness status response
* add comments
* Merge refs/heads/master into slasher_status
* Merge refs/heads/master into slasher_status
2020-07-07 17:11:07 +00:00
Ivan Martinez
d9fea7cb8c [QSP] Deduplicate functions for audit best practices (#6476)
* Deduplicate DB functions and getters

* Rename function

* Reduce to prestons suggestions

* Fix bug

* Fix

* Start changing state db funcs

* Fix tests

* Change return

* Add checks

* Fix test

* Fix

* Nishant comment

* Fix

* Fix

* Fix

* Fix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-07 11:29:25 -05:00
Nishant Das
b868dfa481 Save Archived State (#6503) 2020-07-07 08:04:55 -07:00
Preston Van Loon
46b82eb15d Sync: Verify all block and attestations signatures on finalized blocks by default (#6499)
* Make verifying all signatures the default operation
* Merge branch 'master' into flip-verify-all
* Merge branch 'master' into flip-verify-all
* Merge branch 'master' into flip-verify-all
* Merge branch 'master' into flip-verify-all
2020-07-07 05:13:45 +00:00
Nishant Das
64fa474434 Batch Verify Blocks (#6469)
* add everything so far
* checkpoint progress
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* fix
* checkpoint
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* checkpoint again
* checkpoint again
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* commenting
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* bls cleanup
* revert this back
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* revert core changes
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* add flag
* add test
* add one more test
* clean up
* comment
* lint
* terence's review
* Merge refs/heads/master into fastBLS
* Merge refs/heads/master into fastBLS
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* Merge refs/heads/master into fastBLS
* remove additional method
* Merge branch 'fastBLS' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
* fix
* Merge refs/heads/master into fastBLS
* copy
* Merge branch 'fastBLS' of https://github.com/prysmaticlabs/geth-sharding into fastBLS
2020-07-07 04:16:12 +00:00
Shay Zluf
8ddfde41e3 Historical detection fix (#6455)
* Historical detection before realtime detection

* comment fixes

* remove logs

* remove logs

* remove logs

* gaz

* handle underflow

* add regressiion test

* update test name

* gaz

* gofmt

* fix comment

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-07-07 05:57:40 +03:00
terence tsao
7f741e48e0 Cleanup process block/operation names (#6500) 2020-07-06 18:24:30 -07:00
Preston Van Loon
e96e1f0569 Add a placeholder constant for ignoring cancelled subscription errors from libp2p pubsub. (#6496)
* Add a placeholder constant for ignoring cancelled subscription errors
from libp2p pubsub.

This change temporarily resolves
https://github.com/prysmaticlabs/prysm/issues/6449.

This change should be revisited after
https://github.com/libp2p/go-libp2p-pubsub/pull/356 merges and the prysm
libp2p pubsub dependency is updated.
* Merge branch 'master' into issue-6449
* Merge branch 'master' into issue-6449
* Merge branch 'master' into issue-6449
2020-07-06 23:55:55 +00:00
terence tsao
1a6c55c637 Split block_operations.go into smaller files (#6495) 2020-07-06 15:27:42 -07:00
Jim McDonald
7bb0ee78af Update beacon state locks (#6326)
* Rationalise state locking
* Rationalise state locking
* Merge branch 'state-locks' of github.com:mcdee/prysm into state-locks
* Merge branch 'master' into state-locks
* Add feature flag
* Merge
* Merge branch 'master' into state-locks
* Merge branch 'master' into state-locks
* Update locks
* Merge branch 'master' into state-locks
* Gazelle
* Tidy-ups
* Merge branch 'master' into state-locks
* Remove commentary to a docs.go file for better presentation on godocs
* Add newBeaconStateLocks as a --dev flag
* gofmt
* Merge branch 'master' into state-locks
2020-07-06 20:52:53 +00:00
Preston Van Loon
005a9dde48 CI: Remove GCP remote cache (#6497)
* Remove GCP remote cache as it has been sunset on GCP
2020-07-06 19:25:35 +00:00
terence tsao
def7b602e3 Hot states use no DB (#6488)
* Add cache to service struct
* Update hot getters/setters to use cache
* Update migration
* Update other services to adapt
* Fix initial sync get state
* Update getter related tests
* Update hot related tests
* Update migrate related tests
* New awesome tests for migration
* Clean up rest of the tests
* Merge refs/heads/master into hot-state-no-db
* Fix block chain head tests
* Fix block chain processor tests
* Fixed RPC tests
* Update cold getter and test
* Merge branch 'hot-state-no-db' of github.com:prysmaticlabs/prysm into hot-state-no-db
* Fix sync tests
* Short cut if state is already in DB
* Remove uneeded saves
* Update beacon-chain/state/stategen/hot_test.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/state/stategen/getter_test.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/state/stategen/getter_test.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/state/stategen/service.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/state/stategen/setter_test.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Preston's feedback
* Merge branch 'hot-state-no-db' of github.com:prysmaticlabs/prysm into hot-state-no-db
* Return a copy of cache states
* Remove hot state caches check in StateByRoot
* Merge branch 'hot-state-no-db' of github.com:prysmaticlabs/prysm into hot-state-no-db
* Merge refs/heads/master into hot-state-no-db
* Raul's feedback
* Merge branch 'hot-state-no-db' of github.com:prysmaticlabs/prysm into hot-state-no-db
2020-07-06 17:22:12 +00:00
Nishant Das
fa3da9a6a2 Add In New Core Methods for Batch Verify (#6482)
* add in new core methods

* clean up

* add verification method

* add tests

* add 1 more test

* lint

* Update beacon-chain/core/blocks/block_operations.go

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

* Update beacon-chain/core/blocks/block_operations.go

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

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

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

* terences review

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

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

* fmt

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2020-07-06 11:09:29 +08:00
Ivan Martinez
359b9bef49 Merge separated local slashing protection flags (#6487)
* Merge split-up local protection flags

* Fix deprecated flags

* Fix text
2020-07-03 21:01:54 -05:00
Raul Jordan
d447bb6458 Direct Keymanager: Implement Sign (#6477)
* implement keymanager proto

* utilize proto message and properly comment

* add in godoc

* doc

* add in doc

* sign implementation done

* add documentation for direct keymanager and add lock to signing

* sign method tests

* update godoc

* concrete sign

* fix build

* proper iface
2020-07-03 18:00:02 -05:00
Raul Jordan
8c258278d0 Direct Keymanager: Implement FetchValidatingPublicKeys() (#6475)
* begin on fetch direct
* fetch validating public keys impl
* test for fetch validating keys
* fetch validating public keys done
* helper function and benchmark
* rename package
* viz
* Update validator/accounts/v2/testing/BUILD.bazel

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* gaz
* add lock
* comment
* Merge refs/heads/master into fetch-direct-keys
2020-07-03 20:26:00 +00:00
Ivan Martinez
f0fcebccc4 Move slashing protection code to separate files for proposing and attesting (#6406)
* Get started on cleaning up slashing protection
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-protection
* Move protection functions to own files
* Lint
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-protection
* Begin adding test for proposal protection
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-protection
* Fix build
* Fix tests
* Fix tst
* Fix tests
* Fix proposal tests
* Merge branch 'master' into cleanup-protection
* Merge branch 'master' into cleanup-protection
* Merge branch 'master' into cleanup-protection
* Merge branch 'master' of github.com:prysmaticlabs/prysm into cleanup-protection
* Reorder protections
* Change lock
* Fix test
* Merge branch 'master' into cleanup-protection
* Merge branch 'master' into cleanup-protection
* Merge branch 'master' into cleanup-protection
* Change log
* Merge branch 'cleanup-protection' of github.com:prysmaticlabs/prysm into cleanup-protection
* Merge branch 'master' into cleanup-protection
2020-07-03 19:54:42 +00:00
Raul Jordan
9d979de4ed Direct Keymanager: Implement Account Creation (#6466)
* implementation using petname and keystore
* writing new account to disk along with password
* more logic for properly writing accounts
* print out mnemonic
* save deposit data rlp
* write deposit tx and ssz deposit data to account path
* wrap up account creation
* fix prompt
* generate deposit tx
* direct account creation test
* fix up formatting
* lint
* match formatting
* more sustainable approach towards unmarshaling config file
* resolve feedback
* fix broken import
* comprehensive tests for create account
* tests pass
* Merge branch 'master' into direct-keys
* tidy
* Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys
* Merge refs/heads/master into direct-keys
* gaz
* Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys
* nondeterministic names
* comment
* gaz
* better error wrap
* Merge refs/heads/master into direct-keys
* docker deps
* Merge branch 'direct-keys' of github.com:prysmaticlabs/prysm into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* Merge refs/heads/master into direct-keys
* ivan feedback
* Merge refs/heads/master into direct-keys
* Update validator/accounts/v2/wallet.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* fixed tests and comments
* Merge refs/heads/master into direct-keys
2020-07-03 18:49:16 +00:00
terence tsao
8bb5532377 Epoch boundary cache (#6486)
* Add epoch boundary state cache
* Clean up epoch boundary state cache
* Starting tests
* More tests
* Merge branch 'master' of github.com:prysmaticlabs/prysm into epoch-boundary-cache
* Merge refs/heads/master into epoch-boundary-cache
2020-07-03 17:29:30 +00:00
Victor Farazdagi
688f0d7114 Refactors attestation pool pruning (#6485) 2020-07-03 09:43:56 -07:00
Ivan Martinez
c69b3f568e Move hard-coded constants to global consts (#6467)
* Move hard-coded constants to global consts
* Fixes
* Merge branch 'master' into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Comments
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge refs/heads/master into remove-hard-constants
* Merge branch 'master' of github.com:prysmaticlabs/prysm into remove-hard-constants
2020-07-03 15:25:32 +00:00
Victor Farazdagi
d1f1628478 Restores att-aggregation benchmarks (#6484)
* restores att-aggregation benchmarks
2020-07-03 14:37:54 +00:00
Nishant Das
7896e087e5 Add in Better Logging for Requests (#6483)
* add in better logging
* gaz
* last one
* mess about
* check strings
* fix
2020-07-03 10:08:45 +00:00
Nishant Das
ac9bc5d98b Reset Streams at the End of the Request (#6481)
* close all incoming streams

* use proper helper

* shift to debug

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-03 16:21:18 +08:00
Nishant Das
353229d50a Add New Secure Batch Signature Verification Method (#6479)
* add more tests
* gaz
* Merge refs/heads/master into addBLSMethods
* Merge refs/heads/master into addBLSMethods
* Merge refs/heads/master into addBLSMethods
* Merge refs/heads/master into addBLSMethods
2020-07-03 07:38:13 +00:00
terence tsao
d62e989a67 Minor clean up on state gen package (#6480)
* Remove unused fields and function
* Rename splitInfo to finalizedInfo
* Merge branch 'master' into stategen-cleanup
* Fmt
* Merge branch 'stategen-cleanup' of github.com:prysmaticlabs/prysm into stategen-cleanup
* Merge refs/heads/master into stategen-cleanup
2020-07-03 06:33:58 +00:00
Preston Van Loon
6b9d9e5d3a Add a few test cases to ReceiveBlockNoPubsub with race detection (#6298)
* Add a few test cases to ReceiveBlockNoPubsub with race detection, fix data race in state
* Expose voluntary exits included API. More race condition fixes in state. More tests
* add tests to norace as well for coverage
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-test-coverage-on-receive-block
* PR feedback
* Fixed can't save head in DB by:
1.) Remove new state mgmt condition in SaveHeadBlockRoot
2.) Reuse state summary cache between db and service
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-test-coverage-on-receive-block
* passing tests
* gofmt and goimports
* Merge branch 'master' of github.com:prysmaticlabs/prysm into add-test-coverage-on-receive-block
* lint
* move import and goimport again
* move import and goimport again
* Merge refs/heads/master into add-test-coverage-on-receive-block
* Merge refs/heads/master into add-test-coverage-on-receive-block
* Add bool to selectively record events
* Merge refs/heads/master into add-test-coverage-on-receive-block
* Merge refs/heads/master into add-test-coverage-on-receive-block
* Merge refs/heads/master into add-test-coverage-on-receive-block
* Merge refs/heads/master into add-test-coverage-on-receive-block
2020-07-03 05:46:53 +00:00
dv8silencer
0d2bce8200 Improve consistency in peer connect/disconnect logging (#6409)
* Improve consistency in peer connect/disconnect logging
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Corrected capitalization.  Refactored out duplicated logic
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
* Merge branch 'master' into dv8s-iss6328
2020-07-03 04:44:57 +00:00
Raul Jordan
5b708b54d9 QSP-13 Only Allow Snappy P2P Encoding (#6415)
* enforce only snappy

* fix up tests

* replace with ssz snappy in tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-03 11:24:30 +08:00
Preston Van Loon
aa52e693ce Sync: do not remove attestations from pool on failed block processing (#6474)
* Add test and return error on failed block processing
* use atts in body
* Merge branch 'master' into p2p-potential-error-block
2020-07-02 20:24:30 +00:00
Raul Jordan
091525deb8 Revert Stream Duties (#6473)
* ensure gazelle
* fix up propose test
* build
* comment
2020-07-02 17:50:05 +00:00
Victor Farazdagi
f279cf09b8 Removes excessive concurrency from init-sync queue (#6471)
* Removes excessive concurrency from init-sync queue
* update buffer size
2020-07-02 13:06:12 +00:00
Victor Farazdagi
92c5c651f7 Refactors init-sync: queue streams blocks in batches (#6470)
* init-sync: queue streams blocks in batches
2020-07-02 11:19:07 +00:00
Raul Jordan
2d6f4ebf18 Part 1: Implement Accounts-V2 New, Wallet Creation (#6451)
* begin accounts-v2 new

* password validation

* validator accounts new with eip-2335 keystore

* select different wallet type based on enum

* clean up code significantly

* more robust code structure

* check if wallet exists

* define read and create wallet methods

* fmt

* go mod and comment

* comment

* redundant name

* satify gofmt

* add instructions with keymanager opts

* wrap up create and read wallet functionality

* prep for readiness

* doc improvements

* tests for create and read wallet

* update deps

* tidy

* visibility

* gaz

* fix up

* refactor for proper usage, with wallet and keymanager ifaces

* Update validator/flags/flags.go

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

* import

* improve structure

* wrap up all comments

* simplify

* lint

* Update validator/accounts/v2/cmd.go

* viz check

* add interface methods as needed

* fix build

* lint

* nishant feedback

* simplify structure

* add tests for strong password check

* all feedback done

* ivan feedback

* ivan feedback

Co-authored-by: Ivan Martinez <ivanthegreatdev@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-07-01 16:30:01 -05:00
terence tsao
8c8cc144f1 Archival RPC usages removal (#6453)
* Starting to delete archived rpc usages
* Fixed rest of the tests
* Gaz
* Merge branch 'master' into deprecate-archival-rpc
* Merge branch 'master' into deprecate-archival-rpc
* Merge refs/heads/master into deprecate-archival-rpc
* Merge refs/heads/master into deprecate-archival-rpc
* Merge refs/heads/master into deprecate-archival-rpc
2020-07-01 20:04:02 +00:00
Martin Linkhorst
aeb0b4bf75 Allow to start slasher RPC server with TLS (#6465)
* add warning if slasher server isn't using tls
* pass on tls key and cert to the slasher rpc server
* Merge branch 'master' into slasher-tls
2020-07-01 19:31:29 +00:00
Victor Farazdagi
270a64f059 QSP-BestPractice: Refactors singular/plural KV-store functions (#6462)
* updates SaveBlock
* updates DeleteAttestation
* updates DeleteState
* updates SaveAttestation
* updates SaveState
* updates SaveStateSummary
* Merge refs/heads/master into kv-refactor-singular-pl-methods
* Merge refs/heads/master into kv-refactor-singular-pl-methods
* Merge refs/heads/master into kv-refactor-singular-pl-methods
2020-07-01 18:33:05 +00:00
Preston Van Loon
165cb0d7b4 E2E: Add a check for cold state storage (#6457)
* Add a check for cold state storage
* amend comment
* gaz
* Merge branch 'master' into coldstate-e2e
* Merge refs/heads/master into coldstate-e2e
* Merge refs/heads/master into coldstate-e2e
* PR feedback
* Merge branch 'coldstate-e2e' of github.com:prysmaticlabs/prysm into coldstate-e2e
* Update endtoend/evaluators/data.go
* Merge refs/heads/master into coldstate-e2e
* Merge refs/heads/master into coldstate-e2e
* Merge refs/heads/master into coldstate-e2e
2020-07-01 17:35:05 +00:00
terence tsao
1f3d9873cd Archival service removal (#6448) 2020-07-01 10:04:06 -07:00
Victor Farazdagi
1b0cfb408e QSP-BestPractice: Refactors inline ttfb/resp time constants (#6463)
* refactors inline ttfb/resp time constants
2020-07-01 09:47:59 +00:00
terence tsao
4e180e452d Add spans to db kv's encode and decode (#6458) 2020-06-30 21:00:49 -07:00
terence tsao
8d8da76aa0 API: Fix finalization/justification slot representations (#6443)
* Fix finalized/justified slots representations
* Update tests
* Merge refs/heads/master into use-epochs
* Merge refs/heads/master into use-epochs
* Merge refs/heads/master into use-epochs
* Merge refs/heads/master into use-epochs
* Go fmt
* Merge branch 'use-epochs' of github.com:prysmaticlabs/prysm into use-epochs
* Merge refs/heads/master into use-epochs
* Merge refs/heads/master into use-epochs
* Fixed TestServer_StreamChainHead_OnHeadUpdated
* Merge branch 'use-epochs' of github.com:prysmaticlabs/prysm into use-epochs
* Merge refs/heads/master into use-epochs
2020-06-30 15:17:59 +00:00
Raul Jordan
a0c38c8d0a QSP-33 Check Max Response For All Topics (#6424)
* remove max len funcs

* fix up tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-06-30 09:50:28 -05:00
Nishant Das
21ead0a025 Record Peer Latency (#6456)
* add latency
* Merge branch 'master' into addLatency
* Merge refs/heads/master into addLatency
2020-06-30 03:53:14 +00:00
Preston Van Loon
98e26d1dcc Bulk verify block deposits with BLS (#6454)
* First pass at adding bulk signature verification for block deposits

* checkpoint

* some refactoring to allow for bulk deposit signature verification

* nil check

* fix goimports

* fmt

* rename ProcessPreGenesisDeposit -> ProcessPreGenesisDeposits
2020-06-29 20:52:19 -05:00
terence tsao
1f93a1f4c3 Remove unused prune old states (#6450) 2020-06-29 15:02:31 -07:00
Raul Jordan
6c7131cb54 Fix Concurrent Map Write in gRPC Client Connected Logger (#6446)
* fix up concurrent map write
* fix import
* Merge refs/heads/master into concurrent-write-fix
2020-06-29 15:52:10 +00:00
Victor Farazdagi
196f4c6222 QSP-BestPractice Refactors failover peer selection in init-sync (#6442)
* refactors failover peer selection in init-sync
* Merge refs/heads/master into init-sync-more-effective-failover
2020-06-29 15:23:04 +00:00
Ivan Martinez
e7b24323e6 Move MaxRPCPageSize flag from beacon node to shared/cmd (#6297)
* Allow other clients to set MaxRPCPageSize

* Fixes

* Remove default

* Add init

* Fix default

* Set default

* Fix

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-06-29 09:17:24 -05:00
Preston Van Loon
047880caf2 Change the aggregatedSlotCommitteeIDCacheLock to release the lock immediately after r/w (#6437)
* Change the aggregatedSlotCommitteeIDCacheLock to release the lock immediately after r/w
* Merge branch 'master' into better-validator-lock
* Merge branch 'master' into better-validator-lock
2020-06-29 06:14:21 +00:00
Nishant Das
2bce9c884a Add More Altona Bootnodes (#6441)
* enable noise
* add secio
* Merge branch 'master' of https://github.com/prysmaticlabs/geth-sharding into makeNoiseDefault
* add new bootnodes
2020-06-29 04:02:20 +00:00
Nishant Das
adf9bf7094 QSP 50, QSP 51: Make Noise Default (#6440)
* enable noise

* add secio
2020-06-29 11:19:25 +08:00
Preston Van Loon
bfb6e5e4a0 Use spec attestation time verification in gRPC requests (#6429)
* Re-use attestation time verification

* lint

* fix imports

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-06-28 14:37:17 -07:00
Ivan Martinez
d973c00c6c Slasher detection improvements (#6432)
* Slashing fixes

* Fixess

* Change fatals to error

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-06-28 02:34:21 -04:00
Raul Jordan
417bb45398 Begin Scaffold of Validator Accounts V2 (#6310)
* v2 refactor
* fix up imports
* builds
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge branch 'master' into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* imports keymanager v1
* Update validator/keymanager/v1/remote.go
* Update validator/client/polling/propose.go
* Update validator/keymanager/v1/wallet.go
* fmt
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* Merge refs/heads/master into accounts-revamp-p1
* fix conf
* fix build
* gaz
2020-06-27 15:48:36 +00:00
terence tsao
2a997828a3 Audit best practice feedback - validator DB test folder (#6426)
* Refactor validators db

* Lint

* Lint

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-06-26 21:37:43 -05:00
1104 changed files with 84670 additions and 46845 deletions

View File

@@ -33,9 +33,16 @@ 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
# Release flags
build:release --workspace_status_command=./scripts/workspace_status.sh
build:release --stamp
@@ -69,18 +76,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

@@ -2,24 +2,14 @@
# across machines, developers, and workspaces.
#
# This config is loaded from https://github.com/bazelbuild/bazel-toolchains/blob/master/bazelrc/latest.bazelrc
build:remote-cache --remote_cache=grpcs://remotebuildexecution.googleapis.com
build:remote-cache --remote_timeout=3600
build:remote-cache --auth_enabled=true
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 results backend.
#build:remote-cache --bes_results_url="https://source.cloud.google.com/results/invocations/"
#build:remote-cache --bes_backend=buildeventservice.googleapis.com
#build:remote-cache --bes_timeout=60s
#build:remote-cache --project_id=prysmaticlabs
#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=
build:remote-cache --host_platform_remote_properties_override='properties:{name:\"cache-silo-key\" value:\"prysm\"}'
build:remote-cache --remote_instance_name=projects/prysmaticlabs/instances/default_instance
#build:remote-cache --disk_cache=
build:remote-cache --remote_download_minimal
# Import workspace options.
@@ -47,6 +37,9 @@ build --flaky_test_attempts=5
# Enable kafka for CI tests only.
test --config=kafka_enabled
# Disable blst for CI tests.
test --define blst_enabled=true
build --bes_backend=grpcs://builds.prylabs.net:1985
build --bes_results_url=https://builds.prylabs.net/invocation/

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-*

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,8 +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)
[![fuzzit](https://app.fuzzit.dev/badge?org_id=prysmaticlabs-gh)](https://app.fuzzit.dev/orgs/prysmaticlabs-gh/dashboard)
[![ETH2.0_Spec_Version 0.12.1](https://img.shields.io/badge/ETH2.0%20Spec%20Version-v0.12.1-blue.svg)](https://github.com/ethereum/eth2.0-specs/tree/v0.12.1)
[![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)

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",
],
)
@@ -215,8 +215,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "678c50336ce39bef19b2a0dc69e20a7bda37a673ae07dc0577386e9876e0a525",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.1/general.tar.gz",
sha256 = "7e5f838e0f9110471ef8be9401ea687a8ed4d499664dc0eac34ecfdfd03c2ac3",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.3/general.tar.gz",
)
http_archive(
@@ -231,8 +231,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "d0ce95a3ca0d30df24f96a1b5cfad1f7e6fcc07ad84ca221d92480add051af3e",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.1/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 +247,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "1dfa1ae6822912508dbf6d1fe7608169372daa3ad1e53a3ed0867cb2d6e0ccb0",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.1/mainnet.tar.gz",
sha256 = "63eca02503692a0b6a2d7b70118e0dd62dff094153a3a542af6dbea721841b0d",
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.3/mainnet.tar.gz",
)
http_archive(

View File

@@ -20,6 +20,7 @@ go_library(
"//shared/debug:go_default_library",
"//shared/featureconfig: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",
@@ -28,7 +29,6 @@ go_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",
"@org_uber_go_automaxprocs//:go_default_library",
],
)
@@ -65,7 +65,7 @@ go_image(
"@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",
"@org_uber_go_automaxprocs//:go_default_library",
"//shared/maxprocs:go_default_library",
],
)

View File

@@ -1,46 +0,0 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_library(
name = "go_default_library",
srcs = ["service.go"],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/archiver",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
deps = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],
)

View File

@@ -1,200 +0,0 @@
package archiver
import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
)
var log = logrus.WithField("prefix", "archiver")
// Service defining archiver functionality for persisting checkpointed
// beacon chain information to a database backend for historical purposes.
type Service struct {
ctx context.Context
cancel context.CancelFunc
beaconDB db.NoHeadAccessDatabase
headFetcher blockchain.HeadFetcher
participationFetcher blockchain.ParticipationFetcher
stateNotifier statefeed.Notifier
lastArchivedEpoch uint64
}
// Config options for the archiver service.
type Config struct {
BeaconDB db.NoHeadAccessDatabase
HeadFetcher blockchain.HeadFetcher
ParticipationFetcher blockchain.ParticipationFetcher
StateNotifier statefeed.Notifier
}
// NewArchiverService initializes the service from configuration options.
func NewArchiverService(ctx context.Context, cfg *Config) *Service {
ctx, cancel := context.WithCancel(ctx)
return &Service{
ctx: ctx,
cancel: cancel,
beaconDB: cfg.BeaconDB,
headFetcher: cfg.HeadFetcher,
participationFetcher: cfg.ParticipationFetcher,
stateNotifier: cfg.StateNotifier,
}
}
// Start the archiver service event loop.
func (s *Service) Start() {
go s.run(s.ctx)
}
// Stop the archiver service event loop.
func (s *Service) Stop() error {
defer s.cancel()
return nil
}
// Status reports the healthy status of the archiver. Returning nil means service
// is correctly running without error.
func (s *Service) Status() error {
return nil
}
// We archive committee information pertaining to the head state's epoch.
func (s *Service) archiveCommitteeInfo(ctx context.Context, headState *state.BeaconState, epoch uint64) error {
proposerSeed, err := helpers.Seed(headState, epoch, params.BeaconConfig().DomainBeaconProposer)
if err != nil {
return errors.Wrap(err, "could not generate seed")
}
attesterSeed, err := helpers.Seed(headState, epoch, params.BeaconConfig().DomainBeaconAttester)
if err != nil {
return errors.Wrap(err, "could not generate seed")
}
info := &pb.ArchivedCommitteeInfo{
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
}
if err := s.beaconDB.SaveArchivedCommitteeInfo(ctx, epoch, info); err != nil {
return errors.Wrap(err, "could not archive committee info")
}
return nil
}
// We archive active validator set changes that happened during the previous epoch.
func (s *Service) archiveActiveSetChanges(ctx context.Context, headState *state.BeaconState, epoch uint64) error {
prevEpoch := epoch - 1
vals := headState.Validators()
activations := validators.ActivatedValidatorIndices(prevEpoch, vals)
slashings := validators.SlashedValidatorIndices(prevEpoch, vals)
activeValidatorCount, err := helpers.ActiveValidatorCount(headState, prevEpoch)
if err != nil {
return errors.Wrap(err, "could not get active validator count")
}
exited, err := validators.ExitedValidatorIndices(prevEpoch, vals, activeValidatorCount)
if err != nil {
return errors.Wrap(err, "could not determine exited validator indices")
}
activeSetChanges := &pb.ArchivedActiveSetChanges{
Activated: activations,
Exited: exited,
Slashed: slashings,
}
if err := s.beaconDB.SaveArchivedActiveValidatorChanges(ctx, prevEpoch, activeSetChanges); err != nil {
return errors.Wrap(err, "could not archive active validator set changes")
}
return nil
}
// We compute participation metrics by first retrieving the head state and
// matching validator attestations during the epoch.
func (s *Service) archiveParticipation(ctx context.Context, epoch uint64) error {
pBal := s.participationFetcher.Participation(epoch)
participation := &ethpb.ValidatorParticipation{}
if pBal != nil {
participation = &ethpb.ValidatorParticipation{
EligibleEther: pBal.ActivePrevEpoch,
VotedEther: pBal.PrevEpochTargetAttested,
GlobalParticipationRate: float32(pBal.PrevEpochTargetAttested) / float32(pBal.ActivePrevEpoch),
}
}
return s.beaconDB.SaveArchivedValidatorParticipation(ctx, epoch, participation)
}
// We archive validator balances and active indices.
func (s *Service) archiveBalances(ctx context.Context, balances []uint64, epoch uint64) error {
if err := s.beaconDB.SaveArchivedBalances(ctx, epoch, balances); err != nil {
return errors.Wrap(err, "could not archive balances")
}
return nil
}
func (s *Service) run(ctx context.Context) {
stateChannel := make(chan *feed.Event, 1)
stateSub := s.stateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
for {
select {
case event := <-stateChannel:
if event.Type == statefeed.BlockProcessed {
data, ok := event.Data.(*statefeed.BlockProcessedData)
if !ok {
log.Error("Event feed data is not type *statefeed.BlockProcessedData")
continue
}
log.WithField("headRoot", fmt.Sprintf("%#x", data.BlockRoot)).Debug("Received block processed event")
headState, err := s.headFetcher.HeadState(ctx)
if err != nil {
log.WithError(err).Error("Head state is not available")
continue
}
slot := headState.Slot()
currentEpoch := helpers.SlotToEpoch(slot)
if !helpers.IsEpochEnd(slot) && currentEpoch <= s.lastArchivedEpoch {
continue
}
epochToArchive := currentEpoch
if !helpers.IsEpochEnd(slot) {
epochToArchive--
}
if err := s.archiveCommitteeInfo(ctx, headState, epochToArchive); err != nil {
log.WithError(err).Error("Could not archive committee info")
continue
}
if err := s.archiveActiveSetChanges(ctx, headState, epochToArchive); err != nil {
log.WithError(err).Error("Could not archive active validator set changes")
continue
}
if err := s.archiveParticipation(ctx, epochToArchive); err != nil {
log.WithError(err).Error("Could not archive validator participation")
continue
}
if err := s.archiveBalances(ctx, headState.Balances(), epochToArchive); err != nil {
log.WithError(err).Error("Could not archive validator balances and active indices")
continue
}
log.WithField(
"epoch",
epochToArchive,
).Debug("Successfully archived beacon chain data during epoch")
s.lastArchivedEpoch = epochToArchive
}
case <-s.ctx.Done():
log.Debug("Context closed, exiting goroutine")
return
case err := <-stateSub.Err():
log.WithError(err).Error("Subscription to state feed notifier failed")
return
}
}
}

View File

@@ -1,474 +0,0 @@
package archiver
import (
"context"
"fmt"
"io/ioutil"
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
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/shared/testutil"
"github.com/sirupsen/logrus"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func init() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(ioutil.Discard)
}
func TestArchiverService_ReceivesBlockProcessedEvent(t *testing.T) {
hook := logTest.NewGlobal()
svc, _ := setupService(t)
st := testutil.NewBeaconState()
if err := st.SetSlot(1); err != nil {
t.Fatal(err)
}
svc.headFetcher = &mock.ChainService{
State: st,
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
testutil.AssertLogsContain(t, hook, fmt.Sprintf("%#x", event.Data.(*statefeed.BlockProcessedData).BlockRoot))
testutil.AssertLogsContain(t, hook, "Received block processed event")
}
func TestArchiverService_OnlyArchiveAtEpochEnd(t *testing.T) {
hook := logTest.NewGlobal()
svc, _ := setupService(t)
// The head state is NOT an epoch end.
st := testutil.NewBeaconState()
if err := st.SetSlot(params.BeaconConfig().SlotsPerEpoch - 2); err != nil {
t.Fatal(err)
}
svc.headFetcher = &mock.ChainService{
State: st,
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
// The context should have been canceled.
if svc.ctx.Err() != context.Canceled {
t.Error("context was not canceled")
}
testutil.AssertLogsContain(t, hook, "Received block processed event")
// The service should ONLY log any archival logs if we receive a
// head slot that is an epoch end.
testutil.AssertLogsDoNotContain(t, hook, "Successfully archived")
}
func TestArchiverService_ArchivesEvenThroughSkipSlot(t *testing.T) {
hook := logTest.NewGlobal()
svc, _ := setupService(t)
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
exitRoutine := make(chan bool)
go func() {
svc.run(svc.ctx)
<-exitRoutine
}()
// Send out an event every slot, skipping the end slot of the epoch.
for i := uint64(0); i < params.BeaconConfig().SlotsPerEpoch+1; i++ {
if err := headState.SetSlot(i); err != nil {
t.Fatal(err)
}
svc.headFetcher = &mock.ChainService{
State: headState,
}
if helpers.IsEpochEnd(i) {
continue
}
// Send in a loop to ensure it is delivered (busy wait for the service to subscribe to the state feed).
for sent := 0; sent == 0; {
sent = svc.stateNotifier.StateFeed().Send(event)
}
}
if err := svc.Stop(); err != nil {
t.Fatal(err)
}
exitRoutine <- true
// The context should have been canceled.
if svc.ctx.Err() != context.Canceled {
t.Error("context was not canceled")
}
testutil.AssertLogsContain(t, hook, "Received block processed event")
// Even though there was a skip slot, we should still be able to archive
// upon the next block event afterwards.
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_ComputesAndSavesParticipation(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, _ := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
attestedBalance := uint64(1)
currentEpoch := helpers.CurrentEpoch(headState)
wanted := &ethpb.ValidatorParticipation{
VotedEther: attestedBalance,
EligibleEther: validatorCount * params.BeaconConfig().MaxEffectiveBalance,
GlobalParticipationRate: float32(attestedBalance) / float32(validatorCount*params.BeaconConfig().MaxEffectiveBalance),
}
retrieved, err := svc.beaconDB.ArchivedValidatorParticipation(svc.ctx, currentEpoch)
if err != nil {
t.Fatal(err)
}
if !proto.Equal(wanted, retrieved) {
t.Errorf("Wanted participation for epoch %d %v, retrieved %v", currentEpoch-1, wanted, retrieved)
}
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_SavesIndicesAndBalances(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, _ := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
retrieved, err := svc.beaconDB.ArchivedBalances(svc.ctx, helpers.CurrentEpoch(headState))
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(headState.Balances(), retrieved) {
t.Errorf(
"Wanted balances for epoch %d %v, retrieved %v",
helpers.CurrentEpoch(headState),
headState.Balances(),
retrieved,
)
}
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_SavesCommitteeInfo(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, _ := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
currentEpoch := helpers.CurrentEpoch(headState)
proposerSeed, err := helpers.Seed(headState, currentEpoch, params.BeaconConfig().DomainBeaconProposer)
if err != nil {
t.Fatal(err)
}
attesterSeed, err := helpers.Seed(headState, currentEpoch, params.BeaconConfig().DomainBeaconAttester)
if err != nil {
t.Fatal(err)
}
wanted := &pb.ArchivedCommitteeInfo{
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
}
retrieved, err := svc.beaconDB.ArchivedCommitteeInfo(svc.ctx, helpers.CurrentEpoch(headState))
if err != nil {
t.Fatal(err)
}
if !proto.Equal(wanted, retrieved) {
t.Errorf(
"Wanted committee info for epoch %d %v, retrieved %v",
helpers.CurrentEpoch(headState),
wanted,
retrieved,
)
}
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_SavesActivatedValidatorChanges(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, beaconDB := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
prevEpoch := helpers.PrevEpoch(headState)
delayedActEpoch := helpers.ActivationExitEpoch(prevEpoch)
val1, err := headState.ValidatorAtIndex(4)
if err != nil {
t.Fatal(err)
}
val1.ActivationEpoch = delayedActEpoch
val2, err := headState.ValidatorAtIndex(5)
if err != nil {
t.Fatal(err)
}
val2.ActivationEpoch = delayedActEpoch
if err := headState.UpdateValidatorAtIndex(4, val1); err != nil {
t.Fatal(err)
}
if err := headState.UpdateValidatorAtIndex(5, val1); err != nil {
t.Fatal(err)
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
retrieved, err := beaconDB.ArchivedActiveValidatorChanges(svc.ctx, prevEpoch)
if err != nil {
t.Fatal(err)
}
if retrieved == nil {
t.Fatal("Retrieved indices are nil")
}
if len(retrieved.Activated) != 98 {
t.Error("Did not get wanted active length")
}
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_SavesSlashedValidatorChanges(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, beaconDB := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
prevEpoch := helpers.PrevEpoch(headState)
val1, err := headState.ValidatorAtIndex(95)
if err != nil {
t.Fatal(err)
}
val1.Slashed = true
val2, err := headState.ValidatorAtIndex(96)
if err != nil {
t.Fatal(err)
}
val2.Slashed = true
if err := headState.UpdateValidatorAtIndex(95, val1); err != nil {
t.Fatal(err)
}
if err := headState.UpdateValidatorAtIndex(96, val1); err != nil {
t.Fatal(err)
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
retrieved, err := beaconDB.ArchivedActiveValidatorChanges(svc.ctx, prevEpoch)
if err != nil {
t.Fatal(err)
}
if retrieved == nil {
t.Fatal("Retrieved indices are nil")
}
if !reflect.DeepEqual(retrieved.Slashed, []uint64{95, 96}) {
t.Errorf("Wanted indices 95, 96 slashed, received %v", retrieved.Slashed)
}
testutil.AssertLogsContain(t, hook, "Successfully archived")
}
func TestArchiverService_SavesExitedValidatorChanges(t *testing.T) {
hook := logTest.NewGlobal()
validatorCount := uint64(100)
headState, err := setupState(validatorCount)
if err != nil {
t.Fatal(err)
}
svc, beaconDB := setupService(t)
svc.headFetcher = &mock.ChainService{
State: headState,
}
prevEpoch := helpers.PrevEpoch(headState)
val, err := headState.ValidatorAtIndex(95)
if err != nil {
t.Fatal(err)
}
val.ExitEpoch = prevEpoch
val.WithdrawableEpoch = prevEpoch + params.BeaconConfig().MinValidatorWithdrawabilityDelay
if err := headState.UpdateValidatorAtIndex(95, val); err != nil {
t.Fatal(err)
}
event := &feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
BlockRoot: [32]byte{1, 2, 3},
Verified: true,
},
}
triggerStateEvent(t, svc, event)
testutil.AssertLogsContain(t, hook, "Successfully archived")
retrieved, err := beaconDB.ArchivedActiveValidatorChanges(svc.ctx, prevEpoch)
if err != nil {
t.Fatal(err)
}
if retrieved == nil {
t.Fatal("Retrieved indices are nil")
}
if !reflect.DeepEqual(retrieved.Exited, []uint64{95}) {
t.Errorf("Wanted indices 95 exited, received %v", retrieved.Exited)
}
}
func setupState(validatorCount uint64) (*stateTrie.BeaconState, error) {
validators := make([]*ethpb.Validator, validatorCount)
balances := make([]uint64, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
}
balances[i] = params.BeaconConfig().MaxEffectiveBalance
}
atts := []*pb.PendingAttestation{{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{}}}}
// We initialize a head state that has attestations from participated
// validators in a simulated fashion.
st := testutil.NewBeaconState()
if err := st.SetSlot((2 * params.BeaconConfig().SlotsPerEpoch) - 1); err != nil {
return nil, err
}
if err := st.SetValidators(validators); err != nil {
return nil, err
}
if err := st.SetBalances(balances); err != nil {
return nil, err
}
if err := st.SetCurrentEpochAttestations(atts); err != nil {
return nil, err
}
return st, nil
}
func setupService(t *testing.T) (*Service, db.Database) {
beaconDB, _ := dbutil.SetupDB(t)
ctx, cancel := context.WithCancel(context.Background())
validatorCount := uint64(100)
totalBalance := validatorCount * params.BeaconConfig().MaxEffectiveBalance
mockChainService := &mock.ChainService{}
return &Service{
beaconDB: beaconDB,
ctx: ctx,
cancel: cancel,
stateNotifier: mockChainService.StateNotifier(),
participationFetcher: &mock.ChainService{
Balance: &precompute.Balance{ActivePrevEpoch: totalBalance, PrevEpochTargetAttested: 1}},
}, beaconDB
}
func triggerStateEvent(t *testing.T, svc *Service, event *feed.Event) {
exitRoutine := make(chan bool)
go func() {
svc.run(svc.ctx)
<-exitRoutine
}()
// Send in a loop to ensure it is delivered (busy wait for the service to subscribe to the state feed).
for sent := 0; sent == 0; {
sent = svc.stateNotifier.StateFeed().Send(event)
}
if err := svc.Stop(); err != nil {
t.Fatal(err)
}
exitRoutine <- true
// The context should have been canceled.
if svc.ctx.Err() != context.Canceled {
t.Error("context was not canceled")
}
}

View File

@@ -5,6 +5,7 @@ go_library(
name = "go_default_library",
srcs = [
"chain_info.go",
"checkpoint_info_cache.go",
"head.go",
"info.go",
"init_sync_process_block.go",
@@ -17,9 +18,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",
@@ -41,16 +46,18 @@ 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/hashutil: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_hashicorp_golang_lru//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
@@ -73,15 +80,19 @@ go_test(
size = "medium",
srcs = [
"chain_info_test.go",
"checkpoint_info_cache_test.go",
"head_test.go",
"init_sync_process_block_test.go",
"info_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 = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
@@ -97,6 +108,8 @@ go_test(
"//shared/event: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_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
@@ -114,6 +127,7 @@ go_test(
name = "go_raceon_test",
srcs = [
"chain_info_norace_test.go",
"receive_block_test.go",
"service_norace_test.go",
],
embed = [":go_default_library"],
@@ -127,6 +141,7 @@ go_test(
race = "on",
tags = ["race_on"],
deps = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
@@ -140,6 +155,8 @@ go_test(
"//shared/event: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_ethereum_go_ethereum//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",

View File

@@ -5,15 +5,14 @@ import (
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"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
@@ -58,6 +57,7 @@ type ForkFetcher interface {
// CanonicalFetcher retrieves the current chain's canonical information.
type CanonicalFetcher interface {
IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error)
VerifyBlkDescendant(ctx context.Context, blockRoot [32]byte) error
}
// FinalizationFetcher defines a common interface for methods in blockchain service which
@@ -68,12 +68,6 @@ type FinalizationFetcher interface {
PreviousJustifiedCheckpt() *ethpb.Checkpoint
}
// ParticipationFetcher defines a common interface for methods in blockchain service which
// directly retrieves validator participation related data.
type ParticipationFetcher interface {
Participation(epoch uint64) *precompute.Balance
}
// FinalizedCheckpt returns the latest finalized checkpoint from head state.
func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
if s.finalizedCheckpt == nil {
@@ -125,7 +119,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
}
@@ -148,7 +142,7 @@ func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, erro
// If the head is nil from service struct,
// it will attempt to get the head state from DB.
func (s *Service) HeadState(ctx context.Context) (*state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockchain.HeadState")
ctx, span := trace.StartSpan(ctx, "blockChain.HeadState")
defer span.End()
ok := s.hasHeadState()
@@ -225,14 +219,6 @@ func (s *Service) CurrentFork() *pb.Fork {
return s.head.state.Fork()
}
// Participation returns the participation stats of a given epoch.
func (s *Service) Participation(epoch uint64) *precompute.Balance {
s.epochParticipationLock.RLock()
defer s.epochParticipationLock.RUnlock()
return s.epochParticipation[epoch]
}
// IsCanonical returns true if the input block root is part of the canonical chain.
func (s *Service) IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error) {
// If the block has been finalized, the block will always be part of the canonical chain.

View File

@@ -7,6 +7,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestHeadSlot_DataRace(t *testing.T) {
@@ -15,9 +16,7 @@ func TestHeadSlot_DataRace(t *testing.T) {
beaconDB: db,
}
go func() {
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}()
s.HeadSlot()
}
@@ -30,13 +29,10 @@ func TestHeadRoot_DataRace(t *testing.T) {
stateGen: stategen.New(db, sc),
}
go func() {
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}()
if _, err := s.HeadRoot(context.Background()); err != nil {
t.Fatal(err)
}
_, err := s.HeadRoot(context.Background())
require.NoError(t, err)
}
func TestHeadBlock_DataRace(t *testing.T) {
@@ -47,13 +43,10 @@ func TestHeadBlock_DataRace(t *testing.T) {
stateGen: stategen.New(db, sc),
}
go func() {
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}()
if _, err := s.HeadBlock(context.Background()); err != nil {
t.Fatal(err)
}
_, err := s.HeadBlock(context.Background())
require.NoError(t, err)
}
func TestHeadState_DataRace(t *testing.T) {
@@ -63,11 +56,8 @@ func TestHeadState_DataRace(t *testing.T) {
stateGen: stategen.New(db, sc),
}
go func() {
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}()
if _, err := s.HeadState(context.Background()); err != nil {
t.Fatal(err)
}
_, err := s.HeadState(context.Background())
require.NoError(t, err)
}

View File

@@ -1,9 +1,7 @@
package blockchain
import (
"bytes"
"context"
"reflect"
"testing"
"time"
@@ -12,7 +10,11 @@ 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.
@@ -23,33 +25,25 @@ var _ = ForkFetcher(&Service{})
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) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
headRoot, err := c.HeadRoot(context.Background())
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(headRoot, params.BeaconConfig().ZeroHash[:]) {
t.Error("Incorrect pre chain start value")
}
require.NoError(t, err)
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], headRoot, "Incorrect pre chain start value")
}
func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
db, sc := testDB.SetupDB(t)
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
if c.FinalizedCheckpt().Epoch != cp.Epoch {
t.Errorf("Finalized epoch at genesis should be %d, got: %d", cp.Epoch, c.FinalizedCheckpt().Epoch)
}
assert.Equal(t, cp.Epoch, c.FinalizedCheckpt().Epoch, "Unexpected finalized epoch")
}
func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
@@ -60,22 +54,17 @@ 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
if c.CurrentJustifiedCheckpt().Epoch != cp.Epoch {
t.Errorf("Current Justifiied epoch at genesis should be %d, got: %d", cp.Epoch, c.CurrentJustifiedCheckpt().Epoch)
}
assert.Equal(t, cp.Epoch, c.CurrentJustifiedCheckpt().Epoch, "Unexpected justified epoch")
}
func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
@@ -86,22 +75,16 @@ 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
if c.PreviousJustifiedCheckpt().Epoch != cp.Epoch {
t.Errorf("Previous Justifiied epoch at genesis should be %d, got: %d", cp.Epoch, c.PreviousJustifiedCheckpt().Epoch)
}
assert.Equal(t, cp.Epoch, c.PreviousJustifiedCheckpt().Epoch, "Unexpected previous justified epoch")
}
func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
@@ -112,81 +95,56 @@ 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}
if c.HeadSlot() != 100 {
t.Errorf("Wanted head slot: %d, got: %d", 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'}}
if [32]byte{'A'} != c.headRoot() {
t.Errorf("Wanted head root: %v, got: %d", []byte{'A'}, c.headRoot())
}
assert.Equal(t, [32]byte{'A'}, c.headRoot())
}
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{})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c := &Service{}
c.head = &head{block: b, state: s}
recevied, err := c.HeadBlock(context.Background())
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(b, recevied) {
t.Error("incorrect head block received")
}
require.NoError(t, err)
assert.DeepEqual(t, b, recevied, "Incorrect head block received")
}
func TestHeadState_CanRetrieve(t *testing.T) {
s, err := state.InitializeFromProto(&pb.BeaconState{Slot: 2, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
headState, err := c.HeadState(context.Background())
if err != nil {
t.Fatal(err)
}
if !proto.Equal(s.InnerStateUnsafe(), headState.InnerStateUnsafe()) {
t.Error("incorrect head state received")
}
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Incorrect head state received")
}
func TestGenesisTime_CanRetrieve(t *testing.T) {
c := &Service{genesisTime: time.Unix(999, 0)}
wanted := time.Unix(999, 0)
if c.GenesisTime() != wanted {
t.Error("Did not get wanted genesis time")
}
assert.Equal(t, wanted, c.GenesisTime(), "Did not get wanted genesis time")
}
func TestCurrentFork_CanRetrieve(t *testing.T) {
f := &pb.Fork{Epoch: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Fork: f})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
if !proto.Equal(c.CurrentFork(), f) {
@@ -197,34 +155,24 @@ func TestCurrentFork_CanRetrieve(t *testing.T) {
func TestGenesisValidatorRoot_CanRetrieve(t *testing.T) {
// Should not panic if head state is nil.
c := &Service{}
if c.GenesisValidatorRoot() != [32]byte{} {
t.Error("Did not get correct genesis validator root")
}
assert.Equal(t, [32]byte{}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
s, err := state.InitializeFromProto(&pb.BeaconState{GenesisValidatorsRoot: []byte{'a'}})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c.head = &head{state: s}
if c.GenesisValidatorRoot() != [32]byte{'a'} {
t.Error("Did not get correct genesis validator root")
}
assert.Equal(t, [32]byte{'a'}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
}
func TestHeadETH1Data_Nil(t *testing.T) {
db, sc := testDB.SetupDB(t)
c := setupBeaconChain(t, db, sc)
if !reflect.DeepEqual(c.HeadETH1Data(), &ethpb.Eth1Data{}) {
t.Error("Incorrect pre chain start value")
}
assert.DeepEqual(t, &ethpb.Eth1Data{}, c.HeadETH1Data(), "Incorrect pre chain start value")
}
func TestHeadETH1Data_CanRetrieve(t *testing.T) {
d := &ethpb.Eth1Data{DepositCount: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Eth1Data: d})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
if !proto.Equal(c.HeadETH1Data(), d) {

View File

@@ -0,0 +1,83 @@
package blockchain
import (
"sync"
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
var (
// This defines the max number of checkpoint info this cache can store.
// Each cache is calculated at 3MB(30K validators), the total cache size is around 100MB.
// Due to reorgs and long finality, it's good to keep the old cache around for quickly switch over.
maxInfoSize = 32
// This tracks the number of check point info requests that aren't present in the cache.
infoMiss = promauto.NewCounter(prometheus.CounterOpts{
Name: "check_point_info_cache_miss",
Help: "The number of check point info requests that aren't present in the cache.",
})
// This tracks the number of check point info requests that are in the cache.
infoHit = promauto.NewCounter(prometheus.CounterOpts{
Name: "check_point_info_cache_hit",
Help: "The number of check point info requests that are present in the cache.",
})
)
// checkPtInfoCache is a struct with 1 LRU cache for looking up check point info by checkpoint.
type checkPtInfoCache struct {
cache *lru.Cache
lock sync.RWMutex
}
// newCheckPointInfoCache creates a new checkpoint info cache for storing/accessing processed check point info object.
func newCheckPointInfoCache() *checkPtInfoCache {
cache, err := lru.New(maxInfoSize)
if err != nil {
panic(err)
}
return &checkPtInfoCache{
cache: cache,
}
}
// get fetches check point info by check point. Returns the reference of the CheckPtInfo, nil if doesn't exist.
func (c *checkPtInfoCache) get(cp *ethpb.Checkpoint) (*pb.CheckPtInfo, error) {
c.lock.RLock()
defer c.lock.RUnlock()
h, err := hashutil.HashProto(cp)
if err != nil {
return nil, err
}
item, exists := c.cache.Get(h)
if exists && item != nil {
infoHit.Inc()
// Copy here is unnecessary since the returned check point info object
// will only be used to verify attestation signature.
return item.(*pb.CheckPtInfo), nil
}
infoMiss.Inc()
return nil, nil
}
// put adds CheckPtInfo object to the cache. This method also trims the least
// recently added CheckPtInfo object if the cache size has ready the max cache size limit.
func (c *checkPtInfoCache) put(cp *ethpb.Checkpoint, info *pb.CheckPtInfo) error {
c.lock.Lock()
defer c.lock.Unlock()
h, err := hashutil.HashProto(cp)
if err != nil {
return err
}
c.cache.Add(h, info)
return nil
}

View File

@@ -0,0 +1,41 @@
package blockchain
import (
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestHotStateCache_RoundTrip(t *testing.T) {
c := newCheckPointInfoCache()
cp := &ethpb.Checkpoint{
Epoch: 1,
Root: bytesutil.PadTo([]byte{'a'}, 32),
}
info, err := c.get(cp)
require.NoError(t, err)
require.Equal(t, (*pb.CheckPtInfo)(nil), info)
i := &pb.CheckPtInfo{
Seed: bytesutil.PadTo([]byte{'c'}, 32),
GenesisRoot: bytesutil.PadTo([]byte{'d'}, 32),
ActiveIndices: []uint64{0, 1, 2, 3},
}
require.NoError(t, c.put(cp, i))
info, err = c.get(cp)
require.NoError(t, err)
require.DeepEqual(t, info, i)
}
func TestHotStateCache_CanPrune(t *testing.T) {
c := newCheckPointInfoCache()
for i := 0; i < maxInfoSize+1; i++ {
cp := &ethpb.Checkpoint{Epoch: uint64(i), Root: make([]byte, 32)}
require.NoError(t, c.put(cp, &pb.CheckPtInfo{}))
}
require.Equal(t, len(c.cache.Keys()), maxInfoSize)
}

View File

@@ -1,6 +1,7 @@
package blockchain
import (
"bytes"
"context"
"fmt"
@@ -29,7 +30,7 @@ type head struct {
// Determined the head from the fork choice service and saves its new data
// (head root, head block, and head state) to the local service cache.
func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
ctx, span := trace.StartSpan(ctx, "blockchain.updateHead")
ctx, span := trace.StartSpan(ctx, "blockChain.updateHead")
defer span.End()
// To get the proper head update, a node first checks its best justified
@@ -67,7 +68,7 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
// This saves head info to the local service cache, it also saves the
// new head root to the DB.
func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockchain.saveHead")
ctx, span := trace.StartSpan(ctx, "blockChain.saveHead")
defer span.End()
// Do nothing if head hasn't changed.
@@ -130,21 +131,20 @@ 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) error {
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs *state.BeaconState) error {
cachedHeadRoot, err := s.HeadRoot(ctx)
if err != nil {
return errors.Wrap(err, "could not get head root from cache")
}
if bytes.Equal(r[:], cachedHeadRoot) {
return nil
}
if b == nil || b.Block == nil {
return errors.New("cannot save nil head block")
}
headState, err := s.stateGen.StateByRootInitialSync(ctx, r)
if err != nil {
return errors.Wrap(err, "could not retrieve head state in DB")
}
if headState == nil {
return errors.New("nil head state")
}
s.setHeadInitialSync(r, stateTrie.CopySignedBeaconBlock(b), headState)
s.setHeadInitialSync(r, stateTrie.CopySignedBeaconBlock(b), hs)
return nil
}
@@ -211,7 +211,7 @@ func (s *Service) headBlock() *ethpb.SignedBeaconBlock {
// This returns the head state.
// It does a full copy on head state for immutability.
func (s *Service) headState(ctx context.Context) *stateTrie.BeaconState {
ctx, span := trace.StartSpan(ctx, "blockchain.headState")
ctx, span := trace.StartSpan(ctx, "blockChain.headState")
defer span.End()
s.headLock.RLock()
@@ -239,7 +239,7 @@ func (s *Service) hasHeadState() bool {
// 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")
ctx, span := trace.StartSpan(ctx, "blockChain.updateRecentCanonicalBlocks")
defer span.End()
s.recentCanonicalBlocksLock.Lock()
@@ -253,12 +253,12 @@ func (s *Service) updateRecentCanonicalBlocks(ctx context.Context, headRoot [32]
return nil
}
for node.Parent != protoarray.NonExistentNode {
for node.Parent() != protoarray.NonExistentNode {
if ctx.Err() != nil {
return ctx.Err()
}
node = nodes[node.Parent]
s.recentCanonicalBlocks[node.Root] = true
node = nodes[node.Parent()]
s.recentCanonicalBlocks[node.Root()] = true
}
return nil
@@ -271,20 +271,36 @@ func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot
}
s.clearInitSyncBlocks()
justifiedState, err := s.stateGen.StateByRoot(ctx, justifiedRoot)
if err != nil {
return err
var justifiedState *stateTrie.BeaconState
var err error
if justifiedRoot == s.genesisRoot {
justifiedState, err = s.beaconDB.GenesisState(ctx)
if err != nil {
return err
}
} else {
justifiedState, err = s.stateGen.StateByRoot(ctx, justifiedRoot)
if err != nil {
return err
}
}
if justifiedState == nil {
return errors.New("justified state can't be nil")
}
epoch := helpers.CurrentEpoch(justifiedState)
validators := justifiedState.Validators()
justifiedBalances := make([]uint64, len(validators))
for i, validator := range validators {
if helpers.IsActiveValidator(validator, epoch) {
justifiedBalances[i] = validator.EffectiveBalance
justifiedBalances := make([]uint64, justifiedState.NumValidators())
if err := justifiedState.ReadFromEveryValidator(func(idx int, val *stateTrie.ReadOnlyValidator) error {
if helpers.IsActiveValidatorUsingTrie(val, epoch) {
justifiedBalances[idx] = val.EffectiveBalance()
} else {
justifiedBalances[i] = 0
justifiedBalances[idx] = 0
}
return nil
}); err != nil {
return err
}
s.justifiedBalancesLock.Lock()

View File

@@ -3,14 +3,13 @@ package blockchain
import (
"bytes"
"context"
"reflect"
"testing"
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"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
logTest "github.com/sirupsen/logrus/hooks/test"
)
@@ -21,17 +20,9 @@ func TestSaveHead_Same(t *testing.T) {
r := [32]byte{'A'}
service.head = &head{slot: 0, root: r}
if err := service.saveHead(context.Background(), r); err != nil {
t.Fatal(err)
}
if service.headSlot() != 0 {
t.Error("Head did not stay the same")
}
if service.headRoot() != r {
t.Error("Head did not stay the same")
}
require.NoError(t, service.saveHead(context.Background(), r))
assert.Equal(t, uint64(0), service.headSlot(), "Head did not stay the same")
assert.Equal(t, r, service.headRoot(), "Head did not stay the same")
}
func TestSaveHead_Different(t *testing.T) {
@@ -42,47 +33,28 @@ 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
if err := service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock); err != nil {
t.Fatal(err)
}
newRoot, err := stateutil.BlockRoot(newHeadBlock)
if err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
if err := headState.SetSlot(1); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveState(context.Background(), headState, newRoot); err != nil {
t.Fatal(err)
}
if err := service.saveHead(context.Background(), newRoot); err != nil {
t.Fatal(err)
}
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
if service.HeadSlot() != 1 {
t.Error("Head did not change")
}
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if !bytes.Equal(cachedRoot, newRoot[:]) {
t.Error("Head did not change")
}
if !reflect.DeepEqual(service.headBlock(), newHeadSignedBlock) {
t.Error("Head did not change")
}
if !reflect.DeepEqual(service.headState(ctx).CloneInnerState(), headState.CloneInnerState()) {
t.Error("Head did not change")
}
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
}
func TestSaveHead_Different_Reorg(t *testing.T) {
@@ -95,51 +67,30 @@ 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
if err := service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock); err != nil {
t.Fatal(err)
}
newRoot, err := stateutil.BlockRoot(newHeadBlock)
if err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState := testutil.NewBeaconState()
if err := headState.SetSlot(1); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveState(context.Background(), headState, newRoot); err != nil {
t.Fatal(err)
}
if err := service.saveHead(context.Background(), newRoot); err != nil {
t.Fatal(err)
}
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
if service.HeadSlot() != 1 {
t.Error("Head did not change")
}
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if !bytes.Equal(cachedRoot, newRoot[:]) {
t.Error("Head did not change")
}
if !reflect.DeepEqual(service.headBlock(), newHeadSignedBlock) {
t.Error("Head did not change")
}
if !reflect.DeepEqual(service.headState(ctx).CloneInnerState(), headState.CloneInnerState()) {
t.Error("Head did not change")
}
testutil.AssertLogsContain(t, hook, "Chain reorg occurred")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
require.LogsContain(t, hook, "Chain reorg occurred")
}
func TestUpdateRecentCanonicalBlocks_CanUpdateWithoutParent(t *testing.T) {
@@ -147,58 +98,32 @@ func TestUpdateRecentCanonicalBlocks_CanUpdateWithoutParent(t *testing.T) {
service := setupBeaconChain(t, db, sc)
r := [32]byte{'a'}
if err := service.updateRecentCanonicalBlocks(context.Background(), r); err != nil {
t.Fatal(err)
}
require.NoError(t, service.updateRecentCanonicalBlocks(context.Background(), r))
canonical, err := service.IsCanonical(context.Background(), r)
if err != nil {
t.Fatal(err)
}
if !canonical {
t.Error("Block should be canonical")
}
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'}
if err := service.forkChoiceStore.ProcessBlock(context.Background(), 1, oldHead, [32]byte{'g'}, [32]byte{}, 0, 0); err != nil {
t.Fatal(err)
}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 1, oldHead, [32]byte{'g'}, [32]byte{}, 0, 0))
currentHead := [32]byte{'b'}
if err := service.forkChoiceStore.ProcessBlock(context.Background(), 3, currentHead, oldHead, [32]byte{}, 0, 0); err != nil {
t.Fatal(err)
}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 3, currentHead, oldHead, [32]byte{}, 0, 0))
forkedRoot := [32]byte{'c'}
if err := service.forkChoiceStore.ProcessBlock(context.Background(), 2, forkedRoot, oldHead, [32]byte{}, 0, 0); err != nil {
t.Fatal(err)
}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 2, forkedRoot, oldHead, [32]byte{}, 0, 0))
if err := service.updateRecentCanonicalBlocks(context.Background(), currentHead); err != nil {
t.Fatal(err)
}
require.NoError(t, service.updateRecentCanonicalBlocks(context.Background(), currentHead))
canonical, err := service.IsCanonical(context.Background(), currentHead)
if err != nil {
t.Fatal(err)
}
if !canonical {
t.Error("Block should be canonical")
}
require.NoError(t, err)
assert.Equal(t, true, canonical, "Block should be canonical")
canonical, err = service.IsCanonical(context.Background(), oldHead)
if err != nil {
t.Fatal(err)
}
if !canonical {
t.Error("Block should be canonical")
}
require.NoError(t, err)
assert.Equal(t, true, canonical, "Block should be canonical")
canonical, err = service.IsCanonical(context.Background(), forkedRoot)
if err != nil {
t.Fatal(err)
}
if canonical {
t.Error("Block should not be canonical")
}
require.NoError(t, err)
assert.Equal(t, false, canonical, "Block should not be canonical")
}
func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
@@ -207,16 +132,8 @@ func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
state, _ := testutil.DeterministicGenesisState(t, 100)
r := [32]byte{'a'}
if err := service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveState(context.Background(), state, r); err != nil {
t.Fatal(err)
}
if err := service.cacheJustifiedStateBalances(context.Background(), r); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(state.Balances(), service.getJustifiedBalances()) {
t.Fatal("Incorrect justified balances")
}
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), state, r))
require.NoError(t, service.cacheJustifiedStateBalances(context.Background(), r))
require.DeepEqual(t, service.getJustifiedBalances(), state.Balances(), "Incorrect justified balances")
}

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"github.com/emicklei/dot"
"github.com/prysmaticlabs/prysm/shared/params"
)
const template = `<html>
@@ -50,20 +51,21 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
for i := len(nodes) - 1; i >= 0; i-- {
// Construct label for each node.
slot := fmt.Sprintf("%d", nodes[i].Slot)
weight := fmt.Sprintf("%d", nodes[i].Weight/1e9) // Convert unit Gwei to unit ETH.
votes := fmt.Sprintf("%d", nodes[i].Weight/1e9/avgBalance)
slot := fmt.Sprintf("%d", nodes[i].Slot())
weight := fmt.Sprintf("%d", nodes[i].Weight()/1e9) // Convert unit Gwei to unit ETH.
votes := fmt.Sprintf("%d", nodes[i].Weight()/1e9/avgBalance)
index := fmt.Sprintf("%d", i)
g := nodes[i].Graffiti[:]
g := nodes[i].Graffiti()
graffiti := hex.EncodeToString(g[:8])
label := "slot: " + slot + "\n votes: " + votes + "\n weight: " + weight + "\n graffiti: " + graffiti
var dotN dot.Node
if nodes[i].Parent != ^uint64(0) {
if nodes[i].Parent() != ^uint64(0) {
dotN = graph.Node(index).Box().Attr("label", label)
}
if nodes[i].Slot == s.headSlot() &&
nodes[i].BestDescendant == ^uint64(0) {
if nodes[i].Slot() == s.headSlot() &&
nodes[i].BestDescendant() == ^uint64(0) &&
nodes[i].Parent() != ^uint64(0) {
dotN = dotN.Attr("color", "green")
}
@@ -71,8 +73,8 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
}
for i := len(nodes) - 1; i >= 0; i-- {
if nodes[i].Parent != ^uint64(0) && nodes[i].Parent < uint64(len(dotNodes)) {
graph.Edge(*dotNodes[i], *dotNodes[nodes[i].Parent])
if nodes[i].Parent() != ^uint64(0) && nodes[i].Parent() < uint64(len(dotNodes)) {
graph.Edge(*dotNodes[i], *dotNodes[nodes[i].Parent()])
}
}
@@ -82,3 +84,11 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
log.WithError(err).Error("Failed to render p2p info page")
}
}
func averageBalance(balances []uint64) float64 {
total := uint64(0)
for i := 0; i < len(balances); i++ {
total += balances[i]
}
return float64(total) / float64(len(balances)) / float64(params.BeaconConfig().GweiPerEth)
}

View File

@@ -0,0 +1,47 @@
package blockchain
import (
"context"
"net/http"
"net/http/httptest"
"testing"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestService_TreeHandler(t *testing.T) {
req, err := http.NewRequest("GET", "/tree", nil)
require.NoError(t, err)
ctx := context.Background()
db, sCache := testDB.SetupDB(t)
headState := testutil.NewBeaconState()
require.NoError(t, headState.SetBalances([]uint64{params.BeaconConfig().GweiPerEth}))
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
[32]byte{'a'},
),
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)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(s.TreeHandler)
handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
}

View File

@@ -1,64 +1,9 @@
package blockchain
import (
"context"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
)
func (s *Service) generateState(ctx context.Context, startRoot [32]byte, endRoot [32]byte) (*stateTrie.BeaconState, error) {
preState, err := s.beaconDB.State(ctx, startRoot)
if err != nil {
return nil, err
}
if preState == nil {
if !s.stateGen.HasState(ctx, startRoot) {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return nil, errors.Wrap(err, "could not save initial sync blocks")
}
s.clearInitSyncBlocks()
}
preState, err = s.stateGen.StateByRoot(ctx, startRoot)
if err != nil {
return nil, err
}
if preState == nil {
return nil, errors.New("finalized state does not exist in db")
}
}
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return nil, err
}
var endBlock *ethpb.SignedBeaconBlock
if s.hasInitSyncBlock(endRoot) {
endBlock = s.getInitSyncBlock(endRoot)
s.clearInitSyncBlocks()
} else {
endBlock, err = s.beaconDB.Block(ctx, endRoot)
if err != nil {
return nil, err
}
}
if endBlock == nil {
return nil, errors.New("provided block root does not have block saved in the db")
}
log.Warnf("Generating missing state of slot %d and root %#x", endBlock.Block.Slot, endRoot)
blocks, err := s.stateGen.LoadBlocks(ctx, preState.Slot()+1, endBlock.Block.Slot, endRoot)
if err != nil {
return nil, errors.Wrap(err, "could not load the required blocks")
}
postState, err := s.stateGen.ReplayBlocks(ctx, preState, blocks, endBlock.Block.Slot)
if err != nil {
return nil, errors.Wrap(err, "could not replay the blocks to generate the resultant state")
}
return postState, nil
}
// This saves a beacon block to the initial sync blocks cache.
func (s *Service) saveInitSyncBlock(r [32]byte, b *ethpb.SignedBeaconBlock) {
s.initSyncBlocksLock.Lock()

View File

@@ -1,97 +0,0 @@
package blockchain
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"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/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"gopkg.in/d4l3k/messagediff.v1"
)
func TestGenerateState_CorrectlyGenerated(t *testing.T) {
db, sc := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, StateGen: stategen.New(db, sc)}
service, err := NewService(context.Background(), cfg)
if err != nil {
t.Fatal(err)
}
beaconState, privs := testutil.DeterministicGenesisState(t, 32)
genesisBlock := testutil.NewBeaconBlock()
bodyRoot, err := stateutil.BlockRoot(genesisBlock.Block)
if err != nil {
t.Fatal(err)
}
err = beaconState.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: genesisBlock.Block.Slot,
ParentRoot: genesisBlock.Block.ParentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
BodyRoot: bodyRoot[:],
})
if err != nil {
t.Fatal(err)
}
if err := beaconState.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector)); err != nil {
t.Fatal(err)
}
cp := beaconState.CurrentJustifiedCheckpoint()
mockRoot := [32]byte{}
copy(mockRoot[:], "hello-world")
cp.Root = mockRoot[:]
if err := beaconState.SetCurrentJustifiedCheckpoint(cp); err != nil {
t.Fatal(err)
}
if err := beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}); err != nil {
t.Fatal(err)
}
err = db.SaveBlock(context.Background(), genesisBlock)
if err != nil {
t.Fatal(err)
}
genRoot, err := stateutil.BlockRoot(genesisBlock.Block)
if err != nil {
t.Fatal(err)
}
err = db.SaveState(context.Background(), beaconState, genRoot)
if err != nil {
t.Fatal(err)
}
lastBlock := &ethpb.SignedBeaconBlock{}
for i := uint64(1); i < 10; i++ {
block, err := testutil.GenerateFullBlock(beaconState, privs, testutil.DefaultBlockGenConfig(), i)
if err != nil {
t.Fatal(err)
}
beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, block)
if err != nil {
t.Fatal(err)
}
err = db.SaveBlock(context.Background(), block)
if err != nil {
t.Fatal(err)
}
lastBlock = block
}
root, err := stateutil.BlockRoot(lastBlock.Block)
if err != nil {
t.Fatal(err)
}
newState, err := service.generateState(context.Background(), genRoot, root)
if err != nil {
t.Fatal(err)
}
if !ssz.DeepEqual(newState.InnerStateUnsafe(), beaconState.InnerStateUnsafe()) {
diff, _ := messagediff.PrettyDiff(newState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
t.Errorf("Generated state is different from what is expected: %s", diff)
}
}

View File

@@ -6,7 +6,6 @@ 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/shared/params"
"github.com/sirupsen/logrus"
)
@@ -27,36 +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")
}
func logEpochData(beaconState *stateTrie.BeaconState) {
log.WithFields(logrus.Fields{
"epoch": helpers.CurrentEpoch(beaconState),
"finalizedEpoch": beaconState.FinalizedCheckpointEpoch(),
"justifiedEpoch": beaconState.CurrentJustifiedCheckpoint().Epoch,
"previousJustifiedEpoch": beaconState.PreviousJustifiedCheckpoint().Epoch,
}).Info("Starting next epoch")
activeVals, err := helpers.ActiveValidatorIndices(beaconState, helpers.CurrentEpoch(beaconState))
if err != nil {
log.WithError(err).Error("Could not get active validator indices")
return
}
log.WithFields(logrus.Fields{
"totalValidators": len(beaconState.Validators()),
"activeValidators": len(activeVals),
"averageBalance": fmt.Sprintf("%.5f ETH", averageBalance(beaconState.Balances())),
}).Info("Validator registry information")
}
func averageBalance(balances []uint64) float64 {
total := uint64(0)
for i := 0; i < len(balances); i++ {
total += balances[i]
}
return float64(total) / float64(len(balances)) / float64(params.BeaconConfig().GweiPerEth)
}

View File

@@ -11,7 +11,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"
)
var (
@@ -76,14 +76,26 @@ 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",
@@ -102,6 +114,15 @@ var (
Buckets: []float64{1, 2, 3, 4, 6, 32, 64},
},
)
// TODO(7141): Remove deprecated metrics below.
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",
})
totalVotedTargetBalances = promauto.NewGauge(prometheus.GaugeOpts{
Name: "total_voted_target_balances",
Help: "The total amount of ether, in gwei, that has been used in voting attestation target of previous epoch",
})
)
// reportSlotMetrics reports slot related metrics.
@@ -201,6 +222,14 @@ func reportEpochMetrics(state *stateTrie.BeaconState) {
if precompute.Balances != nil {
totalEligibleBalances.Set(float64(precompute.Balances.ActivePrevEpoch))
totalVotedTargetBalances.Set(float64(precompute.Balances.PrevEpochTargetAttested))
prevEpochActiveBalances.Set(float64(precompute.Balances.ActivePrevEpoch))
prevEpochSourceBalances.Set(float64(precompute.Balances.PrevEpochAttested))
prevEpochTargetBalances.Set(float64(precompute.Balances.PrevEpochTargetAttested))
prevEpochHeadBalances.Set(float64(precompute.Balances.PrevEpochHeadAttested))
}
refMap := state.FieldReferencesCount()
for name, val := range refMap {
stateTrieReferences.WithLabelValues(name).Set(float64(val))
}
}
@@ -210,7 +239,7 @@ func captureSentTimeMetric(genesisTime uint64, currentSlot uint64) error {
if err != nil {
return err
}
diffMs := roughtime.Now().Sub(startTime) / time.Millisecond
diffMs := timeutils.Now().Sub(startTime) / time.Millisecond
sentBlockPropagationHistogram.Observe(float64(diffMs))
return nil

View File

@@ -7,11 +7,13 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"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/timeutils"
"go.opencensus.io/trace"
)
@@ -24,52 +26,26 @@ var ErrTargetRootNotInDB = errors.New("target root does not exist in db")
// The delay is handled by the caller in `processAttestation`.
//
// Spec pseudocode definition:
// def on_attestation(store: Service, attestation: Attestation) -> None:
// def on_attestation(store: Store, attestation: Attestation) -> None:
// """
// Run ``on_attestation`` upon receiving a new ``attestation`` from either within a block or directly on the wire.
//
// An ``attestation`` that is asserted as invalid may be valid at a later time,
// consider scheduling it for later processing in such case.
// """
// target = attestation.data.target
// validate_on_attestation(store, attestation)
// store_target_checkpoint_state(store, attestation.data.target)
//
// # Attestations must be from the current or previous epoch
// current_epoch = compute_epoch_at_slot(get_current_slot(store))
// # Use GENESIS_EPOCH for previous when genesis to avoid underflow
// previous_epoch = current_epoch - 1 if current_epoch > GENESIS_EPOCH else GENESIS_EPOCH
// # If attestation target is from a future epoch, delay consideration until the epoch arrives
// assert target.epoch in [current_epoch, previous_epoch]
// assert target.epoch == compute_epoch_at_slot(attestation.data.slot)
//
// # Attestations target be for a known block. If target block is unknown, delay consideration until the block is found
// assert target.root in store.blocks
//
// # Attestations must be for a known block. If block is unknown, delay consideration until the block is found
// assert attestation.data.beacon_block_root in store.blocks
// # Attestations must not be for blocks in the future. If not, the attestation should not be considered
// assert store.blocks[attestation.data.beacon_block_root].slot <= attestation.data.slot
//
// # Service target checkpoint state if not yet seen
// if target not in store.checkpoint_states:
// process_slots(base_state, compute_start_slot_at_epoch(target.epoch))
// store.checkpoint_states[target] = base_state
// target_state = store.checkpoint_states[target]
//
// # Attestations can only affect the fork choice of subsequent slots.
// # Delay consideration in the fork choice until their slot is in the past.
// assert store.time >= (attestation.data.slot + 1) * SECONDS_PER_SLOT
//
// # Get state at the `target` to validate attestation and calculate the committees
// # Get state at the `target` to fully validate attestation
// target_state = store.checkpoint_states[attestation.data.target]
// indexed_attestation = get_indexed_attestation(target_state, attestation)
// assert is_valid_indexed_attestation(target_state, indexed_attestation)
//
// # Update latest messages
// for i in indexed_attestation.attesting_indices:
// if i not in store.latest_messages or target.epoch > store.latest_messages[i].epoch:
// store.latest_messages[i] = LatestMessage(epoch=target.epoch, root=attestation.data.beacon_block_root)
// # Update latest messages for attesting indices
// update_latest_messages(store, indexed_attestation.attesting_indices, attestation)
// TODO(#6072): This code path is highly untested. Requires comprehensive tests and simpler refactoring.
func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]uint64, error) {
ctx, span := trace.StartSpan(ctx, "blockchain.onAttestation")
ctx, span := trace.StartSpan(ctx, "blockChain.onAttestation")
defer span.End()
if a == nil {
@@ -93,6 +69,53 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]ui
return nil, ErrTargetRootNotInDB
}
if featureconfig.Get().UseCheckPointInfoCache {
c, err := s.AttestationCheckPtInfo(ctx, a)
if err != nil {
return nil, err
}
if err := s.verifyAttTargetEpoch(ctx, uint64(s.genesisTime.Unix()), uint64(timeutils.Now().Unix()), tgt); err != nil {
return nil, err
}
if err := s.verifyBeaconBlock(ctx, a.Data); err != nil {
return nil, errors.Wrap(err, "could not verify attestation beacon block")
}
if err := s.verifyLMDFFGConsistent(ctx, a.Data.Target.Epoch, a.Data.Target.Root, a.Data.BeaconBlockRoot); err != nil {
return nil, errors.Wrap(err, "could not verify attestation beacon block")
}
if err := helpers.VerifySlotTime(uint64(s.genesisTime.Unix()), a.Data.Slot+1, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
}
committee, err := helpers.BeaconCommittee(c.ActiveIndices, bytesutil.ToBytes32(c.Seed), a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return nil, err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, a, committee)
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return nil, err
}
domain, err := helpers.Domain(c.Fork, indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, c.GenesisRoot)
if err != nil {
return nil, err
}
indices := indexedAtt.AttestingIndices
pubkeys := []bls.PublicKey{}
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := c.PubKeys[indices[i]]
pk, err := bls.PublicKeyFromBytes(pubkeyAtIdx)
if err != nil {
return nil, err
}
pubkeys = append(pubkeys, pk)
}
if err := attestationutil.VerifyIndexedAttestationSig(ctx, indexedAtt, pubkeys, domain); err != nil {
return nil, err
}
s.forkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
return indexedAtt.AttestingIndices, nil
}
// Retrieve attestation's data beacon block pre state. Advance pre state to latest epoch if necessary and
// save it to the cache.
baseState, err := s.getAttPreState(ctx, tgt)
@@ -103,7 +126,7 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]ui
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
}
@@ -128,13 +151,6 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) ([]ui
return nil, err
}
// Only save attestation in DB for archival node.
if flags.Get().EnableArchive {
if err := s.beaconDB.SaveAttestation(ctx, a); err != nil {
return nil, err
}
}
if indexedAtt.AttestingIndices == nil {
return nil, errors.New("nil attesting indices")
}

View File

@@ -7,11 +7,11 @@ 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"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
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/params"
@@ -21,6 +21,7 @@ import (
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)
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
@@ -29,37 +30,101 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
return cachedState, nil
}
if !s.stateGen.HasState(ctx, bytesutil.ToBytes32(c.Root)) {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return nil, errors.Wrap(err, "could not save initial sync blocks")
}
s.clearInitSyncBlocks()
}
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() {
epochStartSlot, err := helpers.StartSlot(c.Epoch)
if err != nil {
return nil, err
}
if epochStartSlot > baseState.Slot() {
baseState = baseState.Copy()
baseState, err = state.ProcessSlots(ctx, baseState, helpers.StartSlot(c.Epoch))
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 {
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))
if err != nil {
return nil, err
}
if !has {
if err := s.checkpointState.AddCheckpointState(c, baseState); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
}
}
if err := s.checkpointState.AddCheckpointState(&cache.CheckpointState{
Checkpoint: c,
State: baseState,
}); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
}
return baseState, nil
}
// getAttCheckPtInfo retrieves the check point info given a check point. Check point info enables the node
// to efficiently verify attestation signature without using beacon state. This function utilizes
// the checkpoint info cache and will update the check point info cache on miss.
func (s *Service) getAttCheckPtInfo(ctx context.Context, c *ethpb.Checkpoint, e uint64) (*pb.CheckPtInfo, error) {
// Return checkpoint info if exists in cache.
info, err := s.checkPtInfoCache.get(c)
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
}
if info != nil {
return info, nil
}
// Retrieve checkpoint state to compute checkpoint info.
baseState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for epoch %d", c.Epoch)
}
epochStartSlot, err := helpers.StartSlot(c.Epoch)
if err != nil {
return nil, err
}
if epochStartSlot > baseState.Slot() {
baseState = baseState.Copy()
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
}
f := baseState.Fork()
g := bytesutil.ToBytes32(baseState.GenesisValidatorRoot())
seed, err := helpers.Seed(baseState, e, params.BeaconConfig().DomainBeaconAttester)
if err != nil {
return nil, err
}
indices, err := helpers.ActiveValidatorIndices(baseState, e)
if err != nil {
return nil, err
}
validators := baseState.ValidatorsReadOnly()
pks := make([][]byte, len(validators))
for i := 0; i < len(pks); i++ {
pk := validators[i].PublicKey()
pks[i] = pk[:]
}
// Cache and return the checkpoint info.
info = &pb.CheckPtInfo{
Fork: f,
GenesisRoot: g[:],
Seed: seed[:],
ActiveIndices: indices,
PubKeys: pks,
}
if err := s.checkPtInfoCache.put(c, info); err != nil {
return nil, err
}
return info, 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 {
currentSlot := (nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot
@@ -77,10 +142,16 @@ func (s *Service) verifyAttTargetEpoch(ctx context.Context, genesisTime uint64,
// verifyBeaconBlock verifies beacon head block is known and not from the future.
func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.AttestationData) error {
b, err := s.beaconDB.Block(ctx, bytesutil.ToBytes32(data.BeaconBlockRoot))
r := bytesutil.ToBytes32(data.BeaconBlockRoot)
b, err := s.beaconDB.Block(ctx, r)
if err != nil {
return err
}
// If the block does not exist in db, check again if block exists in initial sync block cache.
// This could happen as the node first syncs to head.
if b == nil && s.hasInitSyncBlock(r) {
b = s.getInitSyncBlock(r)
}
if b == nil || b.Block == nil {
return fmt.Errorf("beacon block %#x does not exist", bytesutil.Trunc(data.BeaconBlockRoot))
}
@@ -92,7 +163,10 @@ 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)
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,22 +2,23 @@ package blockchain
import (
"context"
"strings"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
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/featureconfig"
"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"
)
func TestStore_OnAttestation(t *testing.T) {
@@ -30,130 +31,212 @@ func TestStore_OnAttestation(t *testing.T) {
StateGen: stategen.New(db, sc),
}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
_, err = blockTree1(db, []byte{'g'})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
BlkWithOutState := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 0}}
if err := db.SaveBlock(ctx, BlkWithOutState); err != nil {
t.Fatal(err)
}
BlkWithOutStateRoot, err := stateutil.BlockRoot(BlkWithOutState.Block)
if err != nil {
t.Fatal(err)
}
BlkWithOutState := testutil.NewBeaconBlock()
BlkWithOutState.Block.Slot = 0
require.NoError(t, db.SaveBlock(ctx, BlkWithOutState))
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
require.NoError(t, err)
BlkWithStateBadAtt := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 1}}
if err := db.SaveBlock(ctx, BlkWithStateBadAtt); err != nil {
t.Fatal(err)
}
BlkWithStateBadAttRoot, err := stateutil.BlockRoot(BlkWithStateBadAtt.Block)
if err != nil {
t.Fatal(err)
}
BlkWithStateBadAtt := testutil.NewBeaconBlock()
BlkWithStateBadAtt.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, BlkWithStateBadAtt))
BlkWithStateBadAttRoot, err := BlkWithStateBadAtt.Block.HashTreeRoot()
require.NoError(t, err)
s := testutil.NewBeaconState()
if err := s.SetSlot(100 * params.BeaconConfig().SlotsPerEpoch); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot); err != nil {
t.Fatal(err)
}
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}}
if err := db.SaveBlock(ctx, BlkWithValidState); err != nil {
t.Fatal(err)
}
BlkWithValidState := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
require.NoError(t, db.SaveBlock(ctx, BlkWithValidState))
BlkWithValidStateRoot, err := stateutil.BlockRoot(BlkWithValidState.Block)
if err != nil {
t.Fatal(err)
}
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)
}
if err := service.beaconDB.SaveState(ctx, s, BlkWithValidStateRoot); 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: "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)
}
})
}
}
func TestStore_OnAttestationUsingCheckptCache(t *testing.T) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{UseCheckPointInfoCache: true})
defer resetCfg()
ctx := context.Background()
db, sc := testDB.SetupDB(t)
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(db, sc),
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
_, err = blockTree1(db, []byte{'g'})
require.NoError(t, err)
BlkWithOutState := testutil.NewBeaconBlock()
BlkWithOutState.Block.Slot = 0
require.NoError(t, db.SaveBlock(ctx, BlkWithOutState))
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
require.NoError(t, err)
BlkWithStateBadAtt := testutil.NewBeaconBlock()
BlkWithStateBadAtt.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, BlkWithStateBadAtt))
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 := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
require.NoError(t, db.SaveBlock(ctx, BlkWithValidState))
BlkWithValidStateRoot, err := BlkWithValidState.Block.HashTreeRoot()
require.NoError(t, err)
s = testutil.NewBeaconState()
err = s.SetFork(&pb.Fork{
Epoch: 0,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
tests := []struct {
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{Root: make([]byte, 32)}}},
wantedErr: "data slot is not in the same epoch as target 1 != 0",
},
{
name: "attestation's target root not in db",
a: &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)}}},
wantedErr: "target root does not exist in db",
},
{
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[:]}}},
wantedErr: "target epoch 100 does not match current epoch",
},
{
name: "process nil attestation",
a: nil,
wantedErr: "nil attestation",
},
{
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{
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.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
}
})
}
@@ -168,33 +251,21 @@ func TestStore_SaveCheckpointState(t *testing.T) {
StateGen: stategen.New(db, sc),
}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
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},
})
if err != nil {
t.Fatal(err)
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'}
if err := service.beaconDB.SaveState(ctx, s, r); err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveState(ctx, s, r))
service.justifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
@@ -203,80 +274,43 @@ func TestStore_SaveCheckpointState(t *testing.T) {
r = bytesutil.ToBytes32([]byte{'A'})
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
if err := service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}); err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}))
s1, err := service.getAttPreState(ctx, cp1)
if err != nil {
t.Fatal(err)
}
if s1.Slot() != 1*params.BeaconConfig().SlotsPerEpoch {
t.Errorf("Wanted state slot: %d, got: %d", 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot())
}
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
if err := service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}); err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}))
s2, err := service.getAttPreState(ctx, cp2)
if err != nil {
t.Fatal(err)
}
if s2.Slot() != 2*params.BeaconConfig().SlotsPerEpoch {
t.Errorf("Wanted state slot: %d, got: %d", 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot())
}
require.NoError(t, err)
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
s1, err = service.getAttPreState(ctx, cp1)
if err != nil {
t.Fatal(err)
}
if s1.Slot() != 1*params.BeaconConfig().SlotsPerEpoch {
t.Errorf("Wanted state slot: %d, got: %d", 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot())
}
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
s1, err = service.checkpointState.StateByCheckpoint(cp1)
if err != nil {
t.Fatal(err)
}
if s1.Slot() != 1*params.BeaconConfig().SlotsPerEpoch {
t.Errorf("Wanted state slot: %d, got: %d", 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot())
}
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
s2, err = service.checkpointState.StateByCheckpoint(cp2)
if err != nil {
t.Fatal(err)
}
if s2.Slot() != 2*params.BeaconConfig().SlotsPerEpoch {
t.Errorf("Wanted state slot: %d, got: %d", 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot())
}
require.NoError(t, err)
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
if err := s.SetSlot(params.BeaconConfig().SlotsPerEpoch + 1); err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))
service.justifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
cp3 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, 32)}
if err := service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})); err != nil {
t.Fatal(err)
}
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}); err != nil {
t.Fatal(err)
}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}))
s3, err := service.getAttPreState(ctx, cp3)
if err != nil {
t.Fatal(err)
}
if s3.Slot() != s.Slot() {
t.Errorf("Wanted state slot: %d, got: %d", s.Slot(), s3.Slot())
}
require.NoError(t, err)
assert.Equal(t, s.Slot(), s3.Slot(), "Unexpected state slot")
}
func TestStore_UpdateCheckpointState(t *testing.T) {
@@ -288,56 +322,33 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
StateGen: stategen.New(db, sc),
}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
epoch := uint64(1)
baseState, _ := testutil.DeterministicGenesisState(t, 1)
if err := baseState.SetSlot(epoch * params.BeaconConfig().SlotsPerEpoch); err != nil {
t.Fatal(err)
}
checkpoint := &ethpb.Checkpoint{Epoch: epoch}
if err := service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)); err != nil {
t.Fatal(err)
}
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)
if err != nil {
t.Fatal(err)
}
if baseState.Slot() != returned.Slot() {
t.Error("Incorrectly returned base state")
}
require.NoError(t, err)
assert.Equal(t, returned.Slot(), checkpoint.Epoch*params.BeaconConfig().SlotsPerEpoch, "Incorrectly returned base state")
cached, err := service.checkpointState.StateByCheckpoint(checkpoint)
if err != nil {
t.Fatal(err)
}
if cached == nil {
t.Error("State should have been cached")
}
require.NoError(t, err)
assert.Equal(t, returned.Slot(), cached.Slot(), "State should have been cached")
epoch = uint64(2)
newCheckpoint := &ethpb.Checkpoint{Epoch: epoch}
if err := service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)); err != nil {
t.Fatal(err)
}
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)
if err != nil {
t.Fatal(err)
}
baseState, err = state.ProcessSlots(ctx, baseState, helpers.StartSlot(newCheckpoint.Epoch))
if err != nil {
t.Fatal(err)
}
if baseState.Slot() != returned.Slot() {
t.Error("Incorrectly returned base state")
}
require.NoError(t, err)
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)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if !proto.Equal(returned.InnerStateUnsafe(), cached.InnerStateUnsafe()) {
t.Error("Incorrectly cached base state")
}
@@ -349,17 +360,10 @@ func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
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) {
@@ -368,17 +372,10 @@ func TestAttEpoch_MatchCurrentEpoch(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
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) {
@@ -387,18 +384,11 @@ func TestAttEpoch_NotMatch(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
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) {
@@ -407,14 +397,14 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
d := &ethpb.AttestationData{}
if err := service.verifyBeaconBlock(ctx, d); !strings.Contains(err.Error(), "beacon block does not exist") {
t.Error("Did not receive the wanted error")
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) {
@@ -423,24 +413,16 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 2}}
if err := service.beaconDB.SaveBlock(ctx, b); err != nil {
t.Fatal(err)
}
r, err := stateutil.BlockRoot(b.Block)
if err != nil {
t.Fatal(err)
}
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
err = service.verifyBeaconBlock(ctx, d)
if err == nil || !strings.Contains(err.Error(), "could not process attestation for future block") {
t.Error("Did not receive the wanted error")
}
assert.ErrorContains(t, "could not process attestation for future block", service.verifyBeaconBlock(ctx, d))
}
func TestVerifyBeaconBlock_OK(t *testing.T) {
@@ -449,86 +431,106 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
cfg := &Config{BeaconDB: db}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 2}}
if err := service.beaconDB.SaveBlock(ctx, b); err != nil {
t.Fatal(err)
}
r, err := stateutil.BlockRoot(b.Block)
if err != nil {
t.Fatal(err)
}
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
if err := service.verifyBeaconBlock(ctx, d); err != nil {
t.Error("Did not receive the wanted error")
}
assert.NoError(t, service.verifyBeaconBlock(ctx, d), "Did not receive the wanted error")
}
func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
b32 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 32}}
if err := service.beaconDB.SaveBlock(ctx, b32); err != nil {
t.Fatal(err)
}
r32, err := stateutil.BlockRoot(b32.Block)
if err != nil {
t.Fatal(err)
}
b33 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 33, ParentRoot: r32[:]}}
if err := service.beaconDB.SaveBlock(ctx, b33); err != nil {
t.Fatal(err)
}
r33, err := stateutil.BlockRoot(b33.Block)
if err != nil {
t.Fatal(err)
}
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
wanted := "FFG and LMD votes are not consistent"
if err := service.verifyLMDFFGConsistent(context.Background(), 1, []byte{'a'}, r33[:]); err.Error() != wanted {
t.Error("Did not get wanted error")
}
assert.ErrorContains(t, wanted, service.verifyLMDFFGConsistent(context.Background(), 1, []byte{'a'}, r33[:]))
}
func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db}
cfg := &Config{BeaconDB: db, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
b32 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 32}}
if err := service.beaconDB.SaveBlock(ctx, b32); err != nil {
t.Fatal(err)
}
r32, err := stateutil.BlockRoot(b32.Block)
if err != nil {
t.Fatal(err)
}
b33 := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 33, ParentRoot: r32[:]}}
if err := service.beaconDB.SaveBlock(ctx, b33); err != nil {
t.Fatal(err)
}
r33, err := stateutil.BlockRoot(b33.Block)
if err != nil {
t.Fatal(err)
}
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
if err := service.verifyLMDFFGConsistent(context.Background(), 1, r32[:], r33[:]); err != nil {
t.Errorf("Could not verify LMD and FFG votes to be consistent: %v", err)
}
err = service.verifyLMDFFGConsistent(context.Background(), 1, r32[:], r33[:])
assert.NoError(t, err, "Could not verify LMD and FFG votes to be consistent")
}
func TestGetAttCheckptInfo(t *testing.T) {
ctx := context.Background()
db, _ := testDB.SetupDB(t)
cfg := &Config{BeaconDB: db, StateGen: stategen.New(db, cache.NewStateSummaryCache())}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
baseState, _ := testutil.DeterministicGenesisState(t, 128)
b := testutil.NewBeaconBlock()
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, r))
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, r))
checkpoint := &ethpb.Checkpoint{Root: r[:]}
returned, err := service.getAttCheckPtInfo(ctx, checkpoint, 0)
require.NoError(t, err)
seed, err := helpers.Seed(baseState, 0, params.BeaconConfig().DomainBeaconAttester)
require.NoError(t, err)
indices, err := helpers.ActiveValidatorIndices(baseState, 0)
require.NoError(t, err)
validators := baseState.ValidatorsReadOnly()
pks := make([][]byte, len(validators))
for i := 0; i < len(pks); i++ {
pk := validators[i].PublicKey()
pks[i] = pk[:]
}
wanted := &pb.CheckPtInfo{
Fork: baseState.Fork(),
GenesisRoot: baseState.GenesisValidatorRoot(),
Seed: seed[:],
ActiveIndices: indices,
PubKeys: pks,
}
require.DeepEqual(t, wanted, returned)
cached, err := service.checkPtInfoCache.get(checkpoint)
require.NoError(t, err)
require.DeepEqual(t, wanted, cached)
}

View File

@@ -2,20 +2,18 @@ package blockchain
import (
"context"
"encoding/hex"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -27,152 +25,116 @@ var initialSyncBlockCacheSize = 2 * params.BeaconConfig().SlotsPerEpoch
// computation in this method and methods it calls into.
//
// Spec pseudocode definition:
// def on_block(store: Store, block: BeaconBlock) -> None:
// # Make a copy of the state to avoid mutability issues
// def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
// block = signed_block.message
// # Parent block must be known
// assert block.parent_root in store.block_states
// pre_state = store.block_states[block.parent_root].copy()
// # Make a copy of the state to avoid mutability issues
// pre_state = copy(store.block_states[block.parent_root])
// # Blocks cannot be in the future. If they are, their consideration must be delayed until the are in the past.
// assert store.time >= pre_state.genesis_time + block.slot * SECONDS_PER_SLOT
// # Add new block to the store
// store.blocks[signing_root(block)] = block
// # Check block is a descendant of the finalized block
// assert (
// get_ancestor(store, signing_root(block), store.blocks[store.finalized_checkpoint.root].slot) ==
// store.finalized_checkpoint.root
// )
// # Check that block is later than the finalized epoch slot
// assert block.slot > compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
// assert get_current_slot(store) >= block.slot
//
// # Check that block is later than the finalized epoch slot (optimization to reduce calls to get_ancestor)
// finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
// assert block.slot > finalized_slot
// # Check block is a descendant of the finalized block at the checkpoint finalized slot
// assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root
//
// # Check the block is valid and compute the post-state
// state = state_transition(pre_state, block)
// state = state_transition(pre_state, signed_block, True)
// # Add new block to the store
// store.blocks[hash_tree_root(block)] = block
// # Add new state for this block to the store
// store.block_states[signing_root(block)] = state
// store.block_states[hash_tree_root(block)] = state
//
// # Update justified checkpoint
// if state.current_justified_checkpoint.epoch > store.justified_checkpoint.epoch:
// if state.current_justified_checkpoint.epoch > store.best_justified_checkpoint.epoch:
// store.best_justified_checkpoint = state.current_justified_checkpoint
// if should_update_justified_checkpoint(store, state.current_justified_checkpoint):
// store.justified_checkpoint = state.current_justified_checkpoint
//
// # Update finalized checkpoint
// if state.finalized_checkpoint.epoch > store.finalized_checkpoint.epoch:
// store.finalized_checkpoint = state.finalized_checkpoint
func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockchain.onBlock")
//
// # Potentially update justified if different from store
// if store.justified_checkpoint != state.current_justified_checkpoint:
// # Update justified if new justified is later than store justified
// if state.current_justified_checkpoint.epoch > store.justified_checkpoint.epoch:
// store.justified_checkpoint = state.current_justified_checkpoint
// return
//
// # Update justified if store justified is not in chain with finalized checkpoint
// finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
// store.justified_checkpoint = state.current_justified_checkpoint
func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
defer span.End()
if signed == nil || signed.Block == nil {
return nil, errors.New("nil block")
return errors.New("nil block")
}
b := signed.Block
// Retrieve incoming block's pre state.
preState, err := s.getBlockPreState(ctx, b)
if err != nil {
return nil, err
return err
}
log.WithFields(logrus.Fields{
"slot": b.Slot,
"root": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
}).Debug("Executing state transition on block")
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
if err != nil {
return nil, errors.Wrap(err, "could not execute state transition")
return errors.Wrap(err, "could not execute state transition")
}
if err := s.beaconDB.SaveBlock(ctx, signed); err != nil {
return nil, errors.Wrapf(err, "could not save block from slot %d", b.Slot)
}
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, postState); err != nil {
return nil, errors.Wrapf(err, "could not insert block %d to fork choice store", b.Slot)
}
if err := s.stateGen.SaveState(ctx, blockRoot, postState); err != nil {
return nil, errors.Wrap(err, "could not save state")
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, false /* reg sync */); err != nil {
return err
}
// Update justified check point.
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustified(ctx, postState); err != nil {
return nil, err
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
// Update finalized check point.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return nil, err
return err
}
s.clearInitSyncBlocks()
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, postState.FinalizedCheckpoint()); err != nil {
return nil, errors.Wrap(err, "could not save finalized checkpoint")
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
fRoot := bytesutil.ToBytes32(postState.FinalizedCheckpoint().Root)
// Prune proto array fork choice nodes, all nodes before finalized check point will
// be pruned.
if err := s.forkChoiceStore.Prune(ctx, fRoot); err != nil {
return nil, errors.Wrap(err, "could not prune proto array fork choice nodes")
return errors.Wrap(err, "could not prune proto array fork choice nodes")
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = postState.FinalizedCheckpoint()
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return nil, errors.Wrap(err, "could not save new justified")
return errors.Wrap(err, "could not save new justified")
}
fBlock, err := s.beaconDB.Block(ctx, fRoot)
if err != nil {
return nil, errors.Wrap(err, "could not get finalized block to migrate")
}
if err := s.stateGen.MigrateToCold(ctx, fBlock.Block.Slot, fRoot); err != nil {
return nil, errors.Wrap(err, "could not migrate to cold")
}
}
// Epoch boundary bookkeeping such as logging epoch summaries.
if postState.Slot() >= s.nextEpochBoundarySlot {
logEpochData(postState)
reportEpochMetrics(postState)
// Update committees cache at epoch boundary slot.
if err := helpers.UpdateCommitteeCache(postState, helpers.CurrentEpoch(postState)); err != nil {
return nil, err
}
if err := helpers.UpdateProposerIndicesInCache(postState, helpers.CurrentEpoch(postState)); err != nil {
return nil, err
}
s.nextEpochBoundarySlot = helpers.StartSlot(helpers.NextEpoch(postState))
}
// Delete the processed block attestations from attestation pool.
if err := s.deletePoolAtts(b.Body.Attestations); err != nil {
return nil, err
}
// Delete the processed block attester slashings from slashings pool.
for i := 0; i < len(b.Body.AttesterSlashings); i++ {
s.slashingPool.MarkIncludedAttesterSlashing(b.Body.AttesterSlashings[i])
// Update deposit cache.
s.depositCache.InsertFinalizedDeposits(ctx, int64(postState.Eth1DepositIndex()))
}
defer reportAttestationInclusion(b)
return postState, nil
return s.handleEpochBoundary(postState)
}
// onBlockInitialSyncStateTransition is called when an initial sync block is received.
// It runs state transition on the block and without any BLS verification. The excluded BLS verification
// includes attestation's aggregated signature. It also does not save attestations.
// It runs state transition on the block and without fork choice and post operation pool processes.
// The block's signing root should be computed before calling this method to avoid redundant
// computation in this method and methods it calls into.
func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockchain.onBlock")
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockInitialSyncStateTransition")
defer span.End()
if signed == nil || signed.Block == nil {
@@ -182,12 +144,17 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
b := signed.Block
// Retrieve incoming block's pre state.
preState, err := s.verifyBlkPreState(ctx, b)
if err := s.verifyBlkPreState(ctx, b); err != nil {
return err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(signed.Block.ParentRoot))
if err != nil {
return err
}
// To invalidate cache for parent root because pre state will get mutated.
s.stateGen.DeleteHotStateInCache(bytesutil.ToBytes32(b.ParentRoot))
if preState == nil {
return fmt.Errorf("nil pre state for slot %d", b.Slot)
}
// Exit early if the pre state slot is higher than incoming block's slot.
if preState.Slot() >= signed.Block.Slot {
@@ -204,21 +171,12 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
return errors.Wrap(err, "could not execute state transition")
}
s.saveInitSyncBlock(blockRoot, signed)
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, postState); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Slot)
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, true /* init sync */); err != nil {
return err
}
if err := s.stateGen.SaveState(ctx, blockRoot, postState); err != nil {
return errors.Wrap(err, "could not save state")
}
if flags.Get().EnableArchive {
atts := signed.Block.Body.Attestations
if err := s.beaconDB.SaveAttestations(ctx, atts); err != nil {
return errors.Wrapf(err, "could not save block attestations from slot %d", b.Slot)
}
// Save the latest block as head in cache.
if err := s.saveHeadNoDB(ctx, signed, blockRoot, postState); err != nil {
return err
}
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
@@ -229,35 +187,140 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
s.clearInitSyncBlocks()
}
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, postState.CurrentJustifiedCheckpoint()); err != nil {
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
}
return s.handleEpochBoundary(postState)
}
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
defer span.End()
if len(blks) == 0 || len(blockRoots) == 0 {
return nil, nil, errors.New("no blocks provided")
}
if blks[0] == nil || blks[0].Block == nil {
return nil, nil, errors.New("nil block")
}
b := blks[0].Block
// Retrieve incoming block's pre state.
if err := s.verifyBlkPreState(ctx, b); err != nil {
return nil, nil, err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
if err != nil {
return nil, nil, err
}
if preState == nil {
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot)
}
jCheckpoints := make([]*ethpb.Checkpoint, len(blks))
fCheckpoints := make([]*ethpb.Checkpoint, len(blks))
sigSet := &bls.SignatureSet{
Signatures: [][]byte{},
PublicKeys: []bls.PublicKey{},
Messages: [][32]byte{},
}
var set *bls.SignatureSet
boundaries := make(map[[32]byte]*stateTrie.BeaconState)
for i, b := range blks {
set, preState, err = state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, b)
if err != nil {
return nil, nil, err
}
// 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")
}
}
jCheckpoints[i] = preState.CurrentJustifiedCheckpoint()
fCheckpoints[i] = preState.FinalizedCheckpoint()
sigSet.Join(set)
}
verify, err := sigSet.Verify()
if err != nil {
return nil, nil, err
}
if !verify {
return nil, nil, errors.New("batch block signature verification failed")
}
for r, st := range boundaries {
if err := s.stateGen.SaveState(ctx, r, st); err != nil {
return nil, nil, err
}
}
// Also saves the last post state which to be used as pre state for the next batch.
lastB := blks[len(blks)-1]
lastBR := blockRoots[len(blockRoots)-1]
if err := s.stateGen.SaveState(ctx, lastBR, preState); err != nil {
return nil, nil, err
}
if err := s.saveHeadNoDB(ctx, lastB, lastBR, preState); err != nil {
return nil, nil, err
}
return fCheckpoints, jCheckpoints, nil
}
// 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 {
b := signed.Block
s.saveInitSyncBlock(blockRoot, signed)
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, fCheckpoint, jCheckpoint); err != nil {
return err
}
s.stateGen.SaveStateSummary(ctx, signed, blockRoot)
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
if uint64(len(s.getInitSyncBlocks())) > initialSyncBlockCacheSize {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
}
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, postState.FinalizedCheckpoint()); err != nil {
return errors.Wrap(err, "could not save finalized checkpoint")
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = postState.FinalizedCheckpoint()
fRoot := bytesutil.ToBytes32(postState.FinalizedCheckpoint().Root)
fBlock, err := s.beaconDB.Block(ctx, fRoot)
if err != nil {
return errors.Wrap(err, "could not get finalized block to migrate")
}
if err := s.stateGen.MigrateToCold(ctx, fBlock.Block.Slot, fRoot); err != nil {
return errors.Wrap(err, "could not migrate to cold")
if jCheckpoint.Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, jCheckpoint); err != nil {
return err
}
}
// Epoch boundary bookkeeping such as logging epoch summaries.
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if fCheckpoint.Epoch > s.finalizedCheckpt.Epoch {
if err := s.updateFinalized(ctx, fCheckpoint); err != nil {
return err
}
}
return nil
}
// Epoch boundary bookkeeping such as logging epoch summaries.
func (s *Service) handleEpochBoundary(postState *stateTrie.BeaconState) error {
if postState.Slot() >= s.nextEpochBoundarySlot {
reportEpochMetrics(postState)
s.nextEpochBoundarySlot = helpers.StartSlot(helpers.NextEpoch(postState))
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
@@ -266,25 +329,18 @@ func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed
return err
}
}
return nil
}
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
// to gain information on the most current chain.
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte, state *stateTrie.BeaconState) error {
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, state); err != nil {
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte,
state *stateTrie.BeaconState) error {
fCheckpoint := state.FinalizedCheckpoint()
jCheckpoint := state.CurrentJustifiedCheckpoint()
if err := s.insertBlockToForkChoiceStore(ctx, blk, root, fCheckpoint, jCheckpoint); err != nil {
return err
}
// Feed in block to fork choice store.
if err := s.forkChoiceStore.ProcessBlock(ctx,
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
state.CurrentJustifiedCheckpoint().Epoch,
state.FinalizedCheckpointEpoch()); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
}
// Feed in block's attestations to fork choice store.
for _, a := range blk.Body.Attestations {
committee, err := helpers.BeaconCommitteeFromState(state, a.Data.Slot, a.Data.CommitteeIndex)
@@ -294,6 +350,39 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
indices := attestationutil.AttestingIndices(a.AggregationBits, committee)
s.forkChoiceStore.ProcessAttestation(ctx, indices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
}
return nil
}
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock,
root [32]byte, fCheckpoint *ethpb.Checkpoint, jCheckpoint *ethpb.Checkpoint) error {
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
return err
}
// Feed in block to fork choice store.
if err := s.forkChoiceStore.ProcessBlock(ctx,
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
}
return nil
}
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState, initSync bool) error {
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
defer span.End()
if initSync {
s.saveInitSyncBlock(r, b)
} else if err := s.beaconDB.SaveBlock(ctx, b); err != nil {
return errors.Wrapf(err, "could not save block from slot %d", b.Block.Slot)
}
if err := s.stateGen.SaveState(ctx, r, state); err != nil {
return errors.Wrap(err, "could not save state")
}
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block, r, state); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block.Slot)
}
return nil
}

View File

@@ -9,39 +9,31 @@ 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, "forkChoice.getBlockPreState")
defer span.End()
// Verify incoming block has a valid pre state.
preState, err := s.verifyBlkPreState(ctx, b)
if err != nil {
if err := s.verifyBlkPreState(ctx, b); err != nil {
return nil, err
}
preState, err = s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
}
@@ -54,11 +46,6 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*
return nil, err
}
// Verify block is a descendent of a finalized block.
if err := s.verifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot), b.Slot); err != nil {
return nil, err
}
// Verify block is later than the finalized epoch slot.
if err := s.verifyBlkFinalizedSlot(b); err != nil {
return nil, err
@@ -68,7 +55,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) (*stateTrie.BeaconState, error) {
func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "chainService.verifyBlkPreState")
defer span.End()
@@ -77,48 +64,52 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) (
// during initial syncing. There's no risk given a state summary object is just a
// a subset of the block object.
if !s.stateGen.StateSummaryExists(ctx, parentRoot) && !s.beaconDB.HasBlock(ctx, parentRoot) {
return nil, errors.New("could not reconstruct parent state")
return errors.New("could not reconstruct parent state")
}
if !s.stateGen.HasState(ctx, parentRoot) {
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
}
if !has {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return nil, errors.Wrap(err, "could not save initial sync blocks")
return errors.Wrap(err, "could not save initial sync blocks")
}
s.clearInitSyncBlocks()
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, parentRoot)
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
}
if preState == nil {
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot)
}
return preState, nil // No copy needed from newly hydrated state gen object.
return nil
}
// verifyBlkDescendant validates input block root is a descendant of the
// VerifyBlkDescendant validates input block root is a descendant of the
// current finalized block root.
func (s *Service) verifyBlkDescendant(ctx context.Context, root [32]byte, slot uint64) error {
ctx, span := trace.StartSpan(ctx, "forkchoice.verifyBlkDescendant")
func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error {
ctx, span := trace.StartSpan(ctx, "forkChoice.VerifyBlkDescendant")
defer span.End()
finalizedBlkSigned, err := s.beaconDB.Block(ctx, bytesutil.ToBytes32(s.finalizedCheckpt.Root))
if err != nil || finalizedBlkSigned == nil || finalizedBlkSigned.Block == nil {
return errors.Wrap(err, "could not get finalized block")
fRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.finalizedCheckpt.Root))
finalizedBlkSigned, err := s.beaconDB.Block(ctx, fRoot)
if err != nil {
return err
}
if finalizedBlkSigned == nil || finalizedBlkSigned.Block == nil {
return errors.New("nil finalized block")
}
finalizedBlk := finalizedBlkSigned.Block
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot)
if err != nil {
return errors.Wrap(err, "could not get finalized block root")
}
if bFinalizedRoot == nil {
return fmt.Errorf("no finalized block known for block from slot %d", slot)
return fmt.Errorf("no finalized block known for block %#x", bytesutil.Trunc(root[:]))
}
if !bytes.Equal(bFinalizedRoot, s.finalizedCheckpt.Root) {
err := fmt.Errorf("block from slot %d is not a descendent of the current finalized block slot %d, %#x != %#x",
slot, finalizedBlk.Slot, bytesutil.Trunc(bFinalizedRoot), bytesutil.Trunc(s.finalizedCheckpt.Root))
if !bytes.Equal(bFinalizedRoot, fRoot[:]) {
err := fmt.Errorf("block %#x is not a descendent of the current finalized block slot %d, %#x != %#x",
bytesutil.Trunc(root[:]), finalizedBlk.Slot, bytesutil.Trunc(bFinalizedRoot),
bytesutil.Trunc(fRoot[:]))
traceutil.AnnotateError(span, err)
return err
}
@@ -128,7 +119,10 @@ func (s *Service) verifyBlkDescendant(ctx context.Context, root [32]byte, slot u
// 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)
}
@@ -159,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
@@ -208,6 +206,42 @@ func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconSt
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cpt)
}
// This caches input checkpoint as justified for the service struct. It rotates current justified to previous justified,
// caches justified checkpoint balances for fork choice and save justified checkpoint in DB.
// This method does not have defense against fork choice bouncing attack, which is why it's only recommend to be used during initial syncing.
func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpoint) error {
s.prevJustifiedCheckpt = s.justifiedCheckpt
s.justifiedCheckpt = cp
if err := s.cacheJustifiedStateBalances(ctx, bytesutil.ToBytes32(s.justifiedCheckpt.Root)); err != nil {
return err
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cp)
}
func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) error {
// Blocks need to be saved so that we can retrieve finalized block from
// DB when migrating states.
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
return err
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
fRoot := bytesutil.ToBytes32(cp.Root)
if err := s.stateGen.MigrateToCold(ctx, fRoot); err != nil {
return errors.Wrap(err, "could not migrate to cold")
}
return nil
}
// ancestor returns the block root of an ancestry block from the input block root.
//
// Spec pseudocode definition:
@@ -221,7 +255,7 @@ func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconSt
// # 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, "forkChoice.ancestor")
defer span.End()
// Stop recursive ancestry lookup if context is cancelled.
@@ -229,20 +263,26 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
return nil, ctx.Err()
}
signed, err := s.beaconDB.Block(ctx, bytesutil.ToBytes32(root))
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")
}
if s.hasInitSyncBlock(bytesutil.ToBytes32(root)) {
signed = s.getInitSyncBlock(bytesutil.ToBytes32(root))
if s.hasInitSyncBlock(r) {
signed = s.getInitSyncBlock(r)
}
if signed == nil || signed.Block == nil {
return nil, errors.New("nil block")
}
b := signed.Block
if b.Slot == slot || b.Slot < slot {
return root, nil
}
@@ -277,7 +317,10 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *state
}
// 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 {
@@ -295,13 +338,18 @@ 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, state *stateTrie.BeaconState) error {
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.BeaconBlock,
fCheckpoint *ethpb.Checkpoint, 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)
@@ -312,22 +360,22 @@ 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
}
if err := s.forkChoiceStore.ProcessBlock(ctx,
b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti),
state.CurrentJustifiedCheckpoint().Epoch,
state.FinalizedCheckpointEpoch()); err != nil {
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,11 +10,12 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
"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/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/prysmaticlabs/prysm/shared/timeutils"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -24,6 +25,8 @@ 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)
AttestationCheckPtInfo(ctx context.Context, att *ethpb.Attestation) (*pb.CheckPtInfo, error)
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
}
// ReceiveAttestationNoPubsub is a function that defines the operations that are performed on
@@ -61,7 +64,7 @@ func (s *Service) IsValidAttestation(ctx context.Context, att *ethpb.Attestation
return false
}
if err := blocks.VerifyAttestation(ctx, baseState, att); err != nil {
if err := blocks.VerifyAttestationSignature(ctx, baseState, att); err != nil {
log.WithError(err).Error("Failed to validate attestation")
return false
}
@@ -71,9 +74,34 @@ func (s *Service) IsValidAttestation(ctx context.Context, att *ethpb.Attestation
// 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)
}
// AttestationCheckPtInfo returns the check point info of attestation that can be used to verify the attestation
// contents and signatures.
func (s *Service) AttestationCheckPtInfo(ctx context.Context, att *ethpb.Attestation) (*pb.CheckPtInfo, 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.getAttCheckPtInfo(ctx, att.Data.Target, helpers.SlotToEpoch(att.Data.Slot))
}
// 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)
}
// 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 +117,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.
@@ -131,7 +159,7 @@ 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())
now := uint64(timeutils.Now().Unix())
genesisTime := uint64(s.genesisTime.Unix())
currentSlot := (now - genesisTime) / params.BeaconConfig().SecondsPerSlot
currentEpoch := helpers.SlotToEpoch(currentSlot)

View File

@@ -1,12 +1,16 @@
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/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestVerifyCheckpointEpoch_Ok(t *testing.T) {
@@ -16,11 +20,30 @@ func TestVerifyCheckpointEpoch_Ok(t *testing.T) {
chainService := setupBeaconChain(t, db, sc)
chainService.genesisTime = time.Now()
if !chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{}) {
t.Error("Wanted true, got false")
}
if chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{Epoch: 1}) {
t.Error("Wanted false, got true")
}
assert.Equal(t, true, chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{Root: make([]byte, 32)}))
assert.Equal(t, false, chainService.verifyCheckpointEpoch(&ethpb.Checkpoint{Epoch: 1}))
}
func TestAttestationPreState_FarFutureSlot(t *testing.T) {
helpers.ClearCache()
db, sc := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService.genesisTime = time.Now()
e := helpers.MaxSlotBuffer/params.BeaconConfig().SlotsPerEpoch + 1
_, err := chainService.AttestationCheckPtInfo(context.Background(), &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: e}}})
require.ErrorContains(t, "exceeds max allowed value relative to the local clock", err)
}
func TestAttestationCheckPtInfo_FarFutureSlot(t *testing.T) {
helpers.ClearCache()
db, sc := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
chainService.genesisTime = time.Now()
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

@@ -1,18 +1,13 @@
package blockchain
import (
"bytes"
"context"
"encoding/hex"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"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/featureconfig"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@@ -21,80 +16,31 @@ import (
// 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
ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error
HasInitSyncBlock(root [32]byte) bool
}
// ReceiveBlock is a function that defines the operations that are performed on
// blocks that is received from rpc service. The operations consists of:
// 1. Gossip block to other peers
// 2. Validate block, apply state transition and update check points
// 3. Apply fork choice to the processed block
// 4. Save latest head info
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlock")
defer span.End()
// Broadcast the new block to the network.
if err := s.p2p.Broadcast(ctx, block); err != nil {
return errors.Wrap(err, "could not broadcast block")
}
log.WithFields(logrus.Fields{
"blockRoot": hex.EncodeToString(blockRoot[:]),
}).Debug("Broadcasting block")
if err := captureSentTimeMetric(uint64(s.genesisTime.Unix()), block.Block.Slot); err != nil {
// If a node fails to capture metric, this shouldn't cause the block processing to fail.
log.Warnf("Could not capture block sent time metric: %v", err)
}
if err := s.ReceiveBlockNoPubsub(ctx, block, blockRoot); err != nil {
return err
}
return nil
}
// ReceiveBlockNoPubsub is a function that defines the the operations (minus pubsub)
// ReceiveBlock is a function that defines the the operations (minus pubsub)
// that are performed on blocks that is received from regular sync service. The operations consists of:
// 1. Validate block, apply state transition and update check points
// 2. Apply fork choice to the processed block
// 3. Save latest head info
func (s *Service) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlockNoPubsub")
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
defer span.End()
blockCopy := stateTrie.CopySignedBeaconBlock(block)
// Apply state transition on the new block.
_, err := s.onBlock(ctx, blockCopy, blockRoot)
if err != nil {
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
err := errors.Wrap(err, "could not process block")
traceutil.AnnotateError(span, err)
return err
}
// Add attestations from the block to the pool for fork choice.
if err := s.attPool.SaveBlockAttestations(blockCopy.Block.Body.Attestations); err != nil {
log.Errorf("Could not save attestation for fork choice: %v", err)
return nil
}
for _, exit := range block.Block.Body.VoluntaryExits {
s.exitPool.MarkIncluded(exit)
}
s.epochParticipationLock.Lock()
defer s.epochParticipationLock.Unlock()
s.epochParticipation[helpers.SlotToEpoch(blockCopy.Block.Slot)] = precompute.Balances
if featureconfig.Get().DisableForkChoice && block.Block.Slot > s.headSlot() {
if err := s.saveHead(ctx, blockRoot); err != nil {
return errors.Wrap(err, "could not save head")
}
} else {
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
return errors.Wrap(err, "could not save head")
}
// Update and save head block after fork choice.
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
}
// Send notification of the processed block to the state feed.
@@ -107,6 +53,11 @@ func (s *Service) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.SignedB
},
})
// Handle post block operations such as attestations and exits.
if err := s.handlePostBlockOperations(blockCopy.Block); err != nil {
return err
}
// Reports on block and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.headSlot(), s.CurrentSlot(), s.finalizedCheckpt)
@@ -122,37 +73,24 @@ func (s *Service) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.SignedB
// ReceiveBlockInitialSync processes the input block for the purpose of initial syncing.
// This method should only be used on blocks during initial syncing phase.
func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveBlockNoVerify")
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockNoVerify")
defer span.End()
blockCopy := stateTrie.CopySignedBeaconBlock(block)
// Apply state transition on the incoming newly received blockCopy without verifying its BLS contents.
// Apply state transition on the new block.
if err := s.onBlockInitialSyncStateTransition(ctx, blockCopy, blockRoot); err != nil {
err := errors.Wrap(err, "could not process block")
traceutil.AnnotateError(span, err)
return err
}
cachedHeadRoot, err := s.HeadRoot(ctx)
if err != nil {
return errors.Wrap(err, "could not get head root from cache")
}
if !bytes.Equal(blockRoot[:], cachedHeadRoot) {
if err := s.saveHeadNoDB(ctx, blockCopy, blockRoot); err != nil {
err := errors.Wrap(err, "could not save head")
traceutil.AnnotateError(span, err)
return err
}
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
Verified: false,
Verified: true,
},
})
@@ -166,9 +104,48 @@ func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.Sign
"deposits": len(blockCopy.Block.Body.Deposits),
}).Debug("Finished applying state transition")
s.epochParticipationLock.Lock()
defer s.epochParticipationLock.Unlock()
s.epochParticipation[helpers.SlotToEpoch(blockCopy.Block.Slot)] = precompute.Balances
return nil
}
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
// the state, performing batch verification of all collected signatures and then performing the appropriate
// actions for a block post-transition.
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
defer span.End()
// Apply state transition on the incoming newly received blockCopy without verifying its BLS contents.
fCheckpoints, jCheckpoints, err := s.onBlockBatch(ctx, blocks, blkRoots)
if err != nil {
err := errors.Wrap(err, "could not process block in batch")
traceutil.AnnotateError(span, err)
return err
}
for i, b := range blocks {
blockCopy := stateTrie.CopySignedBeaconBlock(b)
if err = s.handleBlockAfterBatchVerify(ctx, blockCopy, blkRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
traceutil.AnnotateError(span, err)
return err
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blkRoots[i],
Verified: true,
},
})
// Reports on blockCopy and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.headSlot(), s.CurrentSlot(), s.finalizedCheckpt)
}
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)
}
return nil
}
@@ -177,3 +154,26 @@ func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.Sign
func (s *Service) HasInitSyncBlock(root [32]byte) bool {
return s.hasInitSyncBlock(root)
}
func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
// Delete the processed block attestations from attestation pool.
if err := s.deletePoolAtts(b.Body.Attestations); err != nil {
return err
}
// Add block attestations to the fork choice pool to compute head.
if err := s.attPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
log.Errorf("Could not save block attestations for fork choice: %v", err)
return nil
}
// Mark block exits as seen so we don't include same ones in future blocks.
for _, e := range b.Body.VoluntaryExits {
s.exitPool.MarkIncluded(e)
}
// Mark attester slashings as seen so we don't include same ones in future blocks.
for _, as := range b.Body.AttesterSlashings {
s.slashingPool.MarkIncludedAttesterSlashing(as)
}
return nil
}

View File

@@ -0,0 +1,375 @@
package blockchain
import (
"context"
"sync"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"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"
)
func TestService_ReceiveBlock(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
}
bc := params.BeaconConfig()
bc.ShardCommitteePeriod = 0 // Required for voluntary exits test in reasonable time.
params.OverrideBeaconConfig(bc)
type args struct {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if hs := s.head.state.Slot(); hs != 2 {
t.Errorf("Unexpected state slot. Got %d but wanted %d", hs, 2)
}
if bs := s.head.block.Block.Slot; bs != 2 {
t.Errorf("Unexpected head block slot. Got %d but wanted %d", bs, 2)
}
},
},
{
name: "saves attestations to pool",
args: args{
block: genFullBlock(t,
&testutil.BlockGenConfig{
NumProposerSlashings: 0,
NumAttesterSlashings: 0,
NumAttestations: 2,
NumDeposits: 0,
NumVoluntaryExits: 0,
},
1, /*slot*/
),
},
check: func(t *testing.T, s *Service) {
if baCount := len(s.attPool.BlockAttestations()); baCount != 2 {
t.Errorf("Did not get the correct number of block attestations saved to the pool. "+
"Got %d but wanted %d", baCount, 2)
}
},
},
{
name: "updates exit pool",
args: args{
block: genFullBlock(t, &testutil.BlockGenConfig{
NumProposerSlashings: 0,
NumAttesterSlashings: 0,
NumAttestations: 0,
NumDeposits: 0,
NumVoluntaryExits: 3,
},
1, /*slot*/
),
},
check: func(t *testing.T, s *Service) {
var n int
for i := uint64(0); int(i) < genesis.NumValidators(); i++ {
if s.exitPool.HasBeenIncluded(i) {
n++
}
}
if n != 3 {
t.Errorf("Did not mark the correct number of exits. Got %d but wanted %d", n, 3)
}
},
},
{
name: "notifies block processed on state feed",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, db.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
AttPool: attestations.NewPool(),
ExitPool: voluntaryexits.NewPool(),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlock(ctx, tt.args.block, root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
}
}
func TestService_ReceiveBlockUpdateHead(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
b, err := testutil.GenerateFullBlock(genesis, keys, testutil.DefaultBlockGenConfig(), 1)
assert.NoError(t, err)
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, db.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
AttPool: attestations.NewPool(),
ExitPool: voluntaryexits.NewPool(),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
require.NoError(t, s.ReceiveBlock(ctx, b, root))
wg.Done()
}()
wg.Wait()
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
// Verify fork choice has processed the block. (Genesis block and the new block)
assert.Equal(t, 2, len(s.forkChoiceStore.Nodes()))
}
func TestService_ReceiveBlockInitialSync(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
}
type args struct {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
},
},
{
name: "notifies block processed on state feed",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlockInitialSync(ctx, tt.args.block, root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
}
}
func TestService_ReceiveBlockBatch(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
}
type args struct {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
},
},
{
name: "notifies block processed on state feed",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db, stateSummaryCache := testDB.SetupDB(t)
genesisBlockRoot, err := genesis.HashTreeRoot(ctx)
require.NoError(t, err)
cfg := &Config{
BeaconDB: db,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(db, stateSummaryCache),
}
s, err := NewService(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
blks := []*ethpb.SignedBeaconBlock{tt.args.block}
roots := [][32]byte{root}
err = s.ReceiveBlockBatch(ctx, blks, roots)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
}
}
func TestService_HasInitSyncBlock(t *testing.T) {
s, err := NewService(context.Background(), &Config{})
require.NoError(t, err)
r := [32]byte{'a'}
if s.HasInitSyncBlock(r) {
t.Error("Should not have block")
}
s.saveInitSyncBlock(r, testutil.NewBeaconBlock())
if !s.HasInitSyncBlock(r) {
t.Error("Should have block")
}
}

View File

@@ -15,13 +15,11 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
f "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
@@ -32,10 +30,8 @@ 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/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"go.opencensus.io/trace"
@@ -54,13 +50,11 @@ type Service struct {
exitPool *voluntaryexits.Pool
genesisTime time.Time
p2p p2p.Broadcaster
maxRoutines int64
maxRoutines int
head *head
headLock sync.RWMutex
stateNotifier statefeed.Notifier
genesisRoot [32]byte
epochParticipation map[uint64]*precompute.Balance
epochParticipationLock sync.RWMutex
forkChoiceStore f.ForkChoicer
justifiedCheckpt *ethpb.Checkpoint
prevJustifiedCheckpt *ethpb.Checkpoint
@@ -68,10 +62,8 @@ type Service struct {
finalizedCheckpt *ethpb.Checkpoint
prevFinalizedCheckpt *ethpb.Checkpoint
nextEpochBoundarySlot uint64
voteLock sync.RWMutex
initSyncState map[[32]byte]*stateTrie.BeaconState
boundaryRoots [][32]byte
initSyncStateLock sync.RWMutex
checkpointState *cache.CheckpointStateCache
checkpointStateLock sync.Mutex
stateGen *stategen.State
@@ -82,6 +74,10 @@ type Service struct {
recentCanonicalBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
checkPtInfoCache *checkPtInfoCache
wsEpoch uint64
wsRoot []byte
wsVerified bool
}
// Config options for the service.
@@ -94,11 +90,13 @@ type Config struct {
ExitPool *voluntaryexits.Pool
SlashingPool *slashings.Pool
P2p p2p.Broadcaster
MaxRoutines int64
MaxRoutines int
StateNotifier statefeed.Notifier
ForkChoiceStore f.ForkChoicer
OpsService *attestations.Service
StateGen *stategen.State
WspBlockRoot []byte
WspEpoch uint64
}
// NewService instantiates a new block service instance that will
@@ -117,7 +115,6 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
p2p: cfg.P2p,
maxRoutines: cfg.MaxRoutines,
stateNotifier: cfg.StateNotifier,
epochParticipation: make(map[uint64]*precompute.Balance),
forkChoiceStore: cfg.ForkChoiceStore,
initSyncState: make(map[[32]byte]*stateTrie.BeaconState),
boundaryRoots: [][32]byte{},
@@ -127,13 +124,15 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
recentCanonicalBlocks: make(map[[32]byte]bool),
justifiedBalances: make([]uint64, 0),
checkPtInfoCache: newCheckPointInfoCache(),
wsEpoch: cfg.WspEpoch,
wsRoot: cfg.WspBlockRoot,
}, nil
}
// Start a blockchain service's main event loop.
func (s *Service) Start() {
ctx := context.TODO()
beaconState, err := s.beaconDB.HeadState(ctx)
beaconState, err := s.beaconDB.HeadState(s.ctx)
if err != nil {
log.Fatalf("Could not fetch beacon state: %v", err)
}
@@ -141,13 +140,29 @@ func (s *Service) Start() {
// For running initial sync with state cache, in an event of restart, we use
// last finalized check point as start point to sync instead of head
// state. This is because we no longer save state every slot during sync.
cp, err := s.beaconDB.FinalizedCheckpoint(ctx)
cp, err := s.beaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if beaconState == nil {
beaconState, err = s.stateGen.StateByRoot(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 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)
}
@@ -161,25 +176,29 @@ func (s *Service) Start() {
log.Info("Blockchain data already exists in DB, initializing...")
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
s.opsService.SetGenesisTime(beaconState.GenesisTime())
if err := s.initializeChainInfo(ctx); err != nil {
if err := s.initializeChainInfo(s.ctx); err != nil {
log.Fatalf("Could not set up chain info: %v", err)
}
// We start a counter to genesis, if needed.
go slotutil.CountdownToGenesis(ctx, s.genesisTime, uint64(beaconState.NumValidators()))
gState, err := s.beaconDB.GenesisState(s.ctx)
if err != nil {
log.Fatalf("Could not retrieve genesis state: %v", err)
}
go slotutil.CountdownToGenesis(s.ctx, s.genesisTime, uint64(gState.NumValidators()))
justifiedCheckpoint, err := s.beaconDB.JustifiedCheckpoint(ctx)
justifiedCheckpoint, err := s.beaconDB.JustifiedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get justified checkpoint: %v", err)
}
finalizedCheckpoint, err := s.beaconDB.FinalizedCheckpoint(ctx)
finalizedCheckpoint, err := s.beaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get finalized checkpoint: %v", err)
}
// Resume fork choice.
s.justifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
if err := s.cacheJustifiedStateBalances(ctx, bytesutil.ToBytes32(s.justifiedCheckpt.Root)); err != nil {
if err := s.cacheJustifiedStateBalances(s.ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))); err != nil {
log.Fatalf("Could not cache justified state balances: %v", err)
}
s.prevJustifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
@@ -188,6 +207,11 @@ func (s *Service) Start() {
s.prevFinalizedCheckpt = stateTrie.CopyCheckpoint(finalizedCheckpoint)
s.resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint)
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{
@@ -216,7 +240,7 @@ func (s *Service) Start() {
return
}
log.WithField("starttime", data.StartTime).Debug("Received chain start event")
s.processChainStartTime(ctx, data.StartTime)
s.processChainStartTime(s.ctx, data.StartTime)
return
}
case <-s.ctx.Done():
@@ -263,7 +287,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())
@@ -298,13 +322,25 @@ func (s *Service) initializeBeaconChain(
// Stop the blockchain service's main event loop and associated goroutines.
func (s *Service) Stop() error {
defer s.cancel()
if s.stateGen != nil && s.head != nil && s.head.state != nil {
if err := s.stateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
return err
}
}
// Save initial sync cached blocks to the DB before stop.
if err := s.beaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks()); err != nil {
return err
}
return nil
}
// Status always returns nil unless there is an error condition that causes
// this service to be unhealthy.
func (s *Service) Status() error {
if int64(runtime.NumGoroutine()) > s.maxRoutines {
if runtime.NumGoroutine() > s.maxRoutines {
return fmt.Errorf("too many goroutines %d", runtime.NumGoroutine())
}
return nil
@@ -323,7 +359,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")
}
@@ -332,7 +368,7 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.B
if err := s.beaconDB.SaveBlock(ctx, genesisBlk); err != nil {
return errors.Wrap(err, "could not save genesis block")
}
if err := s.stateGen.SaveState(ctx, genesisBlkRoot, genesisState); err != nil {
if err := s.beaconDB.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis state")
}
if err := s.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
@@ -342,6 +378,8 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.B
return err
}
s.stateGen.SaveFinalizedState(0, genesisBlkRoot, genesisState)
if err := s.beaconDB.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save head block root")
}
@@ -385,7 +423,7 @@ 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")
}
@@ -396,7 +434,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
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")
}
@@ -417,40 +455,19 @@ 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")
}
if !featureconfig.Get().SkipRegenHistoricalStates {
// Since historical states were skipped, the node should start from last finalized check point.
finalizedRoot = s.beaconDB.LastArchivedIndexRoot(ctx)
if finalizedRoot == params.BeaconConfig().ZeroHash {
finalizedRoot = bytesutil.ToBytes32(finalized.Root)
}
}
finalizedBlock, err := s.beaconDB.Block(ctx, finalizedRoot)
if err != nil {
return errors.Wrap(err, "could not get finalized block from db")
}
// To skip the regeneration of historical state, the node has to generate the parent of the last finalized state.
// We don't need to do this for genesis.
atGenesis := s.CurrentSlot() == 0
if featureconfig.Get().SkipRegenHistoricalStates && !atGenesis {
parentRoot := bytesutil.ToBytes32(finalizedBlock.Block.ParentRoot)
parentState, err := s.generateState(ctx, finalizedRoot, parentRoot)
if err != nil {
return err
}
if s.beaconDB.SaveState(ctx, parentState, parentRoot) != nil {
return err
}
}
if finalizedState == nil || finalizedBlock == nil {
return errors.New("finalized state and block can't be nil")
}
@@ -459,29 +476,6 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
return nil
}
// This is called when a client starts from a non-genesis slot. It deletes the states in DB
// from slot 1 (avoid genesis state) to `slot`.
func (s *Service) pruneGarbageState(ctx context.Context, slot uint64) error {
if featureconfig.Get().DontPruneStateStartUp {
return nil
}
filter := filters.NewFilter().SetStartSlot(1).SetEndSlot(slot)
roots, err := s.beaconDB.BlockRoots(ctx, filter)
if err != nil {
return err
}
if err := s.beaconDB.DeleteStates(ctx, roots); err != nil {
return err
}
if err := s.beaconDB.SaveLastArchivedIndex(ctx, 0); err != nil {
return err
}
return nil
}
// 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) {

View File

@@ -6,6 +6,7 @@ import (
"testing"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/sirupsen/logrus"
)
@@ -20,11 +21,7 @@ func TestChainService_SaveHead_DataRace(t *testing.T) {
beaconDB: db,
}
go func() {
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}()
if err := s.saveHead(context.Background(), [32]byte{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
}

View File

@@ -11,16 +11,12 @@ 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"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
@@ -28,13 +24,14 @@ 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"
"github.com/prysmaticlabs/prysm/shared/event"
"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"
logTest "github.com/sirupsen/logrus/hooks/test"
)
@@ -93,26 +90,24 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
},
DepositContainers: []*protodb.DepositContainer{},
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
BeaconDB: beaconDB,
HTTPEndPoint: endpoint,
DepositContract: common.Address{},
})
if err != nil {
t.Fatalf("unable to set up web3 service: %v", err)
}
require.NoError(t, err, "Unable to set up web3 service")
opsService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
BeaconBlockBuf: 0,
BeaconDB: beaconDB,
DepositCache: depositcache.NewDepositCache(),
DepositCache: depositCache,
ChainStartFetcher: web3Service,
P2p: &mockBroadcaster{},
StateNotifier: &mockBeaconNode{},
@@ -122,69 +117,16 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database, sc *cache.StateSummary
OpsService: opsService,
}
// Safe a state in stategen to purposes of testing a service stop / shutdown.
require.NoError(t, cfg.StateGen.SaveState(ctx, bytesutil.ToBytes32(bState.FinalizedCheckpoint().Root), bState))
chainService, err := NewService(ctx, cfg)
if err != nil {
t.Fatalf("unable to setup chain service: %v", err)
}
require.NoError(t, err, "Unable to setup chain service")
chainService.genesisTime = time.Unix(1, 0) // non-zero time
return chainService
}
func TestChainStartStop_Uninitialized(t *testing.T) {
hook := logTest.NewGlobal()
db, sc := testDB.SetupDB(t)
chainService := setupBeaconChain(t, db, sc)
// Listen for state events.
stateSubChannel := make(chan *feed.Event, 1)
stateSub := chainService.stateNotifier.StateFeed().Subscribe(stateSubChannel)
// Test the chain start state notifier.
genesisTime := time.Unix(1, 0)
chainService.Start()
event := &feed.Event{
Type: statefeed.ChainStarted,
Data: &statefeed.ChainStartedData{
StartTime: genesisTime,
},
}
// Send in a loop to ensure it is delivered (busy wait for the service to subscribe to the state feed).
for sent := 1; sent == 1; {
sent = chainService.stateNotifier.StateFeed().Send(event)
if sent == 1 {
// Flush our local subscriber.
<-stateSubChannel
}
}
// Now wait for notification the state is ready.
for stateInitialized := false; stateInitialized == false; {
recv := <-stateSubChannel
if recv.Type == statefeed.Initialized {
stateInitialized = true
}
}
stateSub.Unsubscribe()
beaconState, err := db.HeadState(context.Background())
if err != nil {
t.Fatal(err)
}
if beaconState == nil || beaconState.Slot() != 0 {
t.Error("Expected canonical state feed to send a state with genesis block")
}
if err := chainService.Stop(); err != nil {
t.Fatalf("Unable to stop chain service: %v", err)
}
// The context should have been canceled.
if chainService.ctx.Err() != context.Canceled {
t.Error("Context was not canceled")
}
testutil.AssertLogsContain(t, hook, "Waiting")
testutil.AssertLogsContain(t, hook, "Initialized beacon chain genesis state")
}
func TestChainStartStop_Initialized(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
@@ -193,42 +135,51 @@ func TestChainStartStop_Initialized(t *testing.T) {
chainService := setupBeaconChain(t, db, sc)
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := stateutil.BlockRoot(genesisBlk.Block)
if err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(ctx, genesisBlk); err != nil {
t.Fatal(err)
}
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, genesisBlk))
s := testutil.NewBeaconState()
if err := s.SetSlot(1); err != nil {
t.Fatal(err)
}
if err := db.SaveState(ctx, s, blkRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveHeadBlockRoot(ctx, blkRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveGenesisBlockRoot(ctx, blkRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetSlot(1))
require.NoError(t, db.SaveState(ctx, s, blkRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
// Test the start function.
chainService.Start()
if err := chainService.Stop(); err != nil {
t.Fatalf("unable to stop chain service: %v", err)
}
require.NoError(t, chainService.Stop(), "Unable to stop chain service")
// The context should have been canceled.
if chainService.ctx.Err() != context.Canceled {
t.Error("context was not canceled")
}
testutil.AssertLogsContain(t, hook, "data already exists")
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()
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 TestChainService_InitializeBeaconChain(t *testing.T) {
@@ -242,42 +193,28 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
// Set up 10 deposits pre chain start for validators to register
count := uint64(10)
deposits, _, err := testutil.DeterministicDepositsAndKeys(count)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
trie, _, err := testutil.DepositTrieFromDeposits(deposits)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
hashTreeRoot := trie.HashTreeRoot()
genState, err := state.EmptyGenesisState()
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
err = genState.SetEth1Data(&ethpb.Eth1Data{
DepositRoot: hashTreeRoot[:],
DepositCount: uint64(len(deposits)),
BlockHash: make([]byte, 32),
})
for _, deposit := range deposits {
genState, err = b.ProcessPreGenesisDeposit(ctx, genState, deposit)
if err != nil {
t.Fatal(err)
}
}
require.NoError(t, err)
genState, err = b.ProcessPreGenesisDeposits(ctx, genState, deposits)
require.NoError(t, err)
if _, err := bc.initializeBeaconChain(ctx, time.Unix(0, 0), genState, &ethpb.Eth1Data{
DepositRoot: hashTreeRoot[:],
}); err != nil {
t.Fatal(err)
}
_, err = bc.initializeBeaconChain(ctx, time.Unix(0, 0), genState, &ethpb.Eth1Data{DepositRoot: hashTreeRoot[:], BlockHash: make([]byte, 32)})
require.NoError(t, err)
if _, err := bc.HeadState(ctx); err != nil {
t.Error(err)
}
_, err = bc.HeadState(ctx)
assert.NoError(t, err)
headBlk, err := bc.HeadBlock(ctx)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if headBlk == nil {
t.Error("Head state can't be nil after initialize beacon chain")
}
@@ -286,83 +223,102 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
}
}
func TestChainService_CorrectGenesisRoots(t *testing.T) {
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, s.SetSlot(0))
require.NoError(t, db.SaveState(ctx, s, blkRoot))
require.NoError(t, db.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
// Test the start function.
chainService.Start()
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")
}
func TestChainService_InitializeChainInfo(t *testing.T) {
db, sc := testDB.SetupDB(t)
ctx := context.Background()
genesis := testutil.NewBeaconBlock()
genesisRoot, err := stateutil.BlockRoot(genesis.Block)
if err != nil {
t.Fatal(err)
}
if err := db.SaveGenesisBlockRoot(ctx, genesisRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(ctx, genesis); err != nil {
t.Fatal(err)
}
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()
if err := headState.SetSlot(finalizedSlot); err != nil {
t.Fatal(err)
}
if err := headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]); err != nil {
t.Fatal(err)
}
headRoot, err := stateutil.BlockRoot(headBlock.Block)
if err != nil {
t.Fatal(err)
}
if err := db.SaveState(ctx, headState, headRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveState(ctx, headState, genesisRoot); err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(ctx, headBlock); err != nil {
t.Fatal(err)
}
if err := db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{
Epoch: helpers.SlotToEpoch(finalizedSlot),
Root: headRoot[:],
}); err != nil {
t.Fatal(err)
}
require.NoError(t, headState.SetSlot(finalizedSlot))
require.NoError(t, headState.SetGenesisValidatorRoot(params.BeaconConfig().ZeroHash[:]))
headRoot, err := headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, headState, headRoot))
require.NoError(t, db.SaveState(ctx, headState, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, headBlock))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{beaconDB: db, stateGen: stategen.New(db, sc)}
if err := c.initializeChainInfo(ctx); err != nil {
t.Fatal(err)
}
require.NoError(t, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(headBlk, headBlock) {
t.Error("head block incorrect")
}
require.NoError(t, err)
assert.DeepEqual(t, headBlock, headBlk, "Head block incorrect")
s, err := c.HeadState(ctx)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(s.InnerStateUnsafe(), headState.InnerStateUnsafe()) {
t.Error("head state incorrect")
}
if headBlock.Block.Slot != c.HeadSlot() {
t.Error("head slot incorrect")
}
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, c.HeadSlot(), headBlock.Block.Slot, "Head slot incorrect")
r, err := c.HeadRoot(context.Background())
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if !bytes.Equal(headRoot[:], r) {
t.Error("head slot incorrect")
}
if c.genesisRoot != genesisRoot {
t.Error("genesis block root incorrect")
}
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) {
@@ -372,105 +328,54 @@ 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)
if err != nil {
t.Fatal(err)
}
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
r, err := b.HashTreeRoot()
require.NoError(t, err)
newState := testutil.NewBeaconState()
if err := s.stateGen.SaveState(ctx, r, newState); err != nil {
t.Fatal(err)
}
if err := s.saveHeadNoDB(ctx, b, r); err != nil {
t.Fatal(err)
}
require.NoError(t, s.stateGen.SaveState(ctx, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, b, r, newState))
newB, err := s.beaconDB.HeadBlock(ctx)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if reflect.DeepEqual(newB, b) {
t.Error("head block should not be equal")
}
}
func TestChainService_PruneOldStates(t *testing.T) {
db, _ := testDB.SetupDB(t)
ctx := context.Background()
s := &Service{
beaconDB: db,
}
for i := 0; i < 100; i++ {
block := &ethpb.BeaconBlock{Slot: uint64(i)}
if err := s.beaconDB.SaveBlock(ctx, &ethpb.SignedBeaconBlock{Block: block}); err != nil {
t.Fatal(err)
}
r, err := stateutil.BlockRoot(block)
if err != nil {
t.Fatal(err)
}
newState := testutil.NewBeaconState()
if err := newState.SetSlot(uint64(i)); err != nil {
t.Fatal(err)
}
if err := s.beaconDB.SaveState(ctx, newState, r); err != nil {
t.Fatal(err)
}
}
// Delete half of the states.
if err := s.pruneGarbageState(ctx, 50); err != nil {
t.Fatal(err)
}
filter := filters.NewFilter().SetStartSlot(1).SetEndSlot(100)
roots, err := s.beaconDB.BlockRoots(ctx, filter)
if err != nil {
t.Fatal(err)
}
for i := 1; i < 50; i++ {
s, err := s.beaconDB.State(ctx, roots[i])
if err != nil {
t.Fatal(err)
}
if s != nil {
t.Errorf("wanted nil for slot %d", i)
}
}
}
func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
ctx := context.Background()
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)
if err != nil {
t.Fatal(err)
}
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{}}
state, err := beaconstate.InitializeFromProto(bs)
if err != nil {
t.Fatal(err)
}
if err := s.insertBlockToForkChoiceStore(ctx, block.Block, r, state); err != nil {
t.Fatal(err)
}
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))
if s.hasBlock(ctx, [32]byte{}) {
t.Error("Should not have block")
}
assert.Equal(t, false, s.hasBlock(ctx, [32]byte{}), "Should not have block")
assert.Equal(t, true, s.hasBlock(ctx, r), "Should have block")
}
if !s.hasBlock(ctx, r) {
t.Error("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) {
@@ -479,20 +384,14 @@ func BenchmarkHasBlockDB(b *testing.B) {
s := &Service{
beaconDB: db,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{}}
if err := s.beaconDB.SaveBlock(ctx, block); err != nil {
b.Fatal(err)
}
r, err := stateutil.BlockRoot(block.Block)
if err != nil {
b.Fatal(err)
}
block := testutil.NewBeaconBlock()
require.NoError(b, s.beaconDB.SaveBlock(ctx, block))
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if !s.beaconDB.HasBlock(ctx, r) {
b.Fatal("Block is not in DB")
}
require.Equal(b, true, s.beaconDB.HasBlock(ctx, r), "Block is not in DB")
}
}
@@ -501,27 +400,19 @@ 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)
if err != nil {
b.Fatal(err)
}
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{}}
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}}
state, err := beaconstate.InitializeFromProto(bs)
if err != nil {
b.Fatal(err)
}
if err := s.insertBlockToForkChoiceStore(ctx, block.Block, r, state); err != nil {
b.Fatal(err)
}
require.NoError(b, err)
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, state))
b.ResetTimer()
for i := 0; i < b.N; i++ {
if !s.forkChoiceStore.HasNode(r) {
b.Fatal("Block is not in fork choice store")
}
require.Equal(b, true, s.forkChoiceStore.HasNode(r), "Block is not in fork choice store")
}
}

View File

@@ -11,6 +11,7 @@ go_library(
],
deps = [
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/block:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
@@ -18,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

@@ -5,11 +5,13 @@ package testing
import (
"bytes"
"context"
"sync"
"time"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
blockfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/block"
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
@@ -17,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"
@@ -44,6 +46,7 @@ type ChainService struct {
opNotifier opfeed.Notifier
ValidAttestation bool
ForkChoiceStore *protoarray.Store
VerifyBlkDescendantErr error
}
// StateNotifier mocks the same method in the chain service.
@@ -78,12 +81,40 @@ func (msn *MockBlockNotifier) BlockFeed() *event.Feed {
// MockStateNotifier mocks the state notifier.
type MockStateNotifier struct {
feed *event.Feed
recv []*feed.Event
recvLock sync.Mutex
recvCh chan *feed.Event
RecordEvents bool
}
// ReceivedEvents returns the events received by the state feed in this mock.
func (msn *MockStateNotifier) ReceivedEvents() []*feed.Event {
msn.recvLock.Lock()
defer msn.recvLock.Unlock()
return msn.recv
}
// StateFeed returns a state feed.
func (msn *MockStateNotifier) StateFeed() *event.Feed {
if msn.feed == nil {
if msn.feed == nil && msn.recvCh == nil {
msn.feed = new(event.Feed)
if msn.RecordEvents {
msn.recvCh = make(chan *feed.Event)
sub := msn.feed.Subscribe(msn.recvCh)
go func() {
select {
case evt := <-msn.recvCh:
msn.recvLock.Lock()
msn.recv = append(msn.recv, evt)
msn.recvLock.Unlock()
case <-sub.Err():
sub.Unsubscribe()
}
}()
}
}
return msn.feed
}
@@ -109,11 +140,6 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
return mon.feed
}
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
return nil
}
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
if ms.State == nil {
@@ -126,7 +152,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
}
@@ -141,8 +167,37 @@ func (ms *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethp
return nil
}
// ReceiveBlockNoPubsub mocks ReceiveBlockNoPubsub method in chain service.
func (ms *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
// ReceiveBlockBatch processes blocks in batches from initial-sync.
func (ms *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, roots [][32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
}
for _, block := range blks {
if !bytes.Equal(ms.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", ms.Root, block.Block.ParentRoot)
}
if err := ms.State.SetSlot(block.Block.Slot); err != nil {
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
if err != nil {
return err
}
if ms.DB != nil {
if err := ms.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
}
ms.Root = signingRoot[:]
ms.Block = block
}
return nil
}
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (ms *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
if ms.State == nil {
ms.State = &stateTrie.BeaconState{}
}
@@ -153,7 +208,7 @@ func (ms *ChainService) ReceiveBlockNoPubsub(ctx context.Context, block *ethpb.S
return err
}
ms.BlocksReceived = append(ms.BlocksReceived, block)
signingRoot, err := stateutil.BlockRoot(block.Block)
signingRoot, err := block.Block.HashTreeRoot()
if err != nil {
return err
}
@@ -178,8 +233,10 @@ 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
if len(ms.Root) > 0 {
return ms.Root, nil
}
return make([]byte, 32), nil
}
// HeadBlock mocks HeadBlock method in chain service.
@@ -293,3 +350,43 @@ func (ms *ChainService) HasInitSyncBlock(root [32]byte) bool {
func (ms *ChainService) HeadGenesisValidatorRoot() [32]byte {
return [32]byte{}
}
// VerifyBlkDescendant mocks VerifyBlkDescendant and always returns nil.
func (ms *ChainService) VerifyBlkDescendant(ctx context.Context, root [32]byte) error {
return ms.VerifyBlkDescendantErr
}
// VerifyLmdFfgConsistency mocks VerifyLmdFfgConsistency and always returns nil.
func (ms *ChainService) VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error {
return nil
}
// AttestationCheckPtInfo mocks AttestationCheckPtInfo and always returns nil.
func (ms *ChainService) AttestationCheckPtInfo(ctx 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,27 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
# gazelle:ignore committee_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",
],
] + select({
"//fuzz:fuzzing_enabled": [
"committee_disabled.go",
],
"//conditions:default": [
"committee.go",
],
}),
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/cache",
visibility = [
"//beacon-chain:__subpackages__",
@@ -56,8 +64,9 @@ go_test(
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",

View File

@@ -7,6 +7,7 @@ import (
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
)
func TestAttestationCache_RoundTrip(t *testing.T) {
@@ -19,34 +20,20 @@ func TestAttestationCache_RoundTrip(t *testing.T) {
}
response, err := c.Get(ctx, req)
if err != nil {
t.Error(err)
}
assert.NoError(t, err)
assert.Equal(t, (*ethpb.AttestationData)(nil), response)
if response != nil {
t.Errorf("Empty cache returned an object: %v", response)
}
if err := c.MarkInProgress(req); err != nil {
t.Error(err)
}
assert.NoError(t, c.MarkInProgress(req))
res := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 5},
Target: &ethpb.Checkpoint{Epoch: 5, Root: make([]byte, 32)},
}
if err = c.Put(ctx, req, res); err != nil {
t.Error(err)
}
if err := c.MarkNotInProgress(req); err != nil {
t.Error(err)
}
assert.NoError(t, c.Put(ctx, req, res))
assert.NoError(t, c.MarkNotInProgress(req))
response, err = c.Get(ctx, req)
if err != nil {
t.Error(err)
}
assert.NoError(t, err)
if !proto.Equal(response, res) {
t.Error("Expected equal protos to return from cache")

View File

@@ -4,12 +4,12 @@ import (
"errors"
"sync"
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"k8s.io/client-go/tools/cache"
)
var (
@@ -20,11 +20,11 @@ var (
// 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.
maxCheckpointStateSize = uint64(10)
maxCheckpointStateSize = 10
// Metrics.
checkpointStateMiss = promauto.NewCounter(prometheus.CounterOpts{
Name: "check_point_statecache_miss",
Name: "check_point_state_cache_miss",
Help: "The number of check point state requests that aren't present in the cache.",
})
checkpointStateHit = promauto.NewCounter(prometheus.CounterOpts{
@@ -33,36 +33,20 @@ var (
})
)
// CheckpointState defines the active validator indices per epoch.
type CheckpointState struct {
Checkpoint *ethpb.Checkpoint
State *stateTrie.BeaconState
}
// CheckpointStateCache is a struct with 1 queue for looking up state by checkpoint.
type CheckpointStateCache struct {
cache *cache.FIFO
cache *lru.Cache
lock sync.RWMutex
}
// checkpointState takes the checkpoint as the key of the resulting state.
func checkpointState(obj interface{}) (string, error) {
info, ok := obj.(*CheckpointState)
if !ok {
return "", ErrNotCheckpointState
}
h, err := hashutil.HashProto(info.Checkpoint)
if err != nil {
return "", err
}
return string(h[:]), nil
}
// NewCheckpointStateCache creates a new checkpoint state cache for storing/accessing processed state.
func NewCheckpointStateCache() *CheckpointStateCache {
cache, err := lru.New(maxCheckpointStateSize)
if err != nil {
panic(err)
}
return &CheckpointStateCache{
cache: cache.NewFIFO(checkpointState),
cache: cache,
}
}
@@ -76,44 +60,27 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
return nil, err
}
obj, exists, err := c.cache.GetByKey(string(h[:]))
if err != nil {
return nil, err
}
item, exists := c.cache.Get(h)
if exists {
if exists && item != nil {
checkpointStateHit.Inc()
} else {
checkpointStateMiss.Inc()
return nil, nil
// Copy here is unnecessary since the return will only be used to verify attestation signature.
return item.(*stateTrie.BeaconState), nil
}
info, ok := obj.(*CheckpointState)
if !ok {
return nil, ErrNotCheckpointState
}
// Copy here is unnecessary since the return will only be used to verify attestation signature.
return info.State, nil
checkpointStateMiss.Inc()
return nil, nil
}
// AddCheckpointState adds CheckpointState object to the cache. This method also trims the least
// recently added CheckpointState object if the cache size has ready the max cache size limit.
func (c *CheckpointStateCache) AddCheckpointState(cp *CheckpointState) error {
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s *stateTrie.BeaconState) error {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.cache.AddIfNotPresent(&CheckpointState{
Checkpoint: stateTrie.CopyCheckpoint(cp.Checkpoint),
State: cp.State.Copy(),
}); err != nil {
h, err := hashutil.HashProto(cp)
if err != nil {
return err
}
trim(c.cache, maxCheckpointStateSize)
c.cache.Add(h, s)
return nil
}
// CheckpointStateKeys returns the keys of the state in cache.
func (c *CheckpointStateCache) CheckpointStateKeys() []string {
return c.cache.ListKeys()
}

View File

@@ -1,7 +1,6 @@
package cache
import (
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
@@ -9,42 +8,11 @@ import (
stateTrie "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/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestCheckpointStateCacheKeyFn_OK(t *testing.T) {
cp := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 64,
})
if err != nil {
t.Fatal(err)
}
info := &CheckpointState{
Checkpoint: cp,
State: st,
}
key, err := checkpointState(info)
if err != nil {
t.Fatal(err)
}
wantedKey, err := hashutil.HashProto(cp)
if err != nil {
t.Fatal(err)
}
if key != string(wantedKey[:]) {
t.Errorf("Incorrect hash key: %s, expected %s", key, string(wantedKey[:]))
}
}
func TestCheckpointStateCacheKeyFn_InvalidObj(t *testing.T) {
_, err := checkpointState("bad")
if err != ErrNotCheckpointState {
t.Errorf("Expected error %v, got %v", ErrNotCheckpointState, err)
}
}
func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
cache := NewCheckpointStateCache()
@@ -53,29 +21,18 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:],
Slot: 64,
})
if err != nil {
t.Fatal(err)
}
info1 := &CheckpointState{
Checkpoint: cp1,
State: st,
}
state, err := cache.StateByCheckpoint(cp1)
if err != nil {
t.Fatal(err)
}
if state != nil {
t.Error("Expected state not to exist in empty cache")
}
require.NoError(t, err)
state, err := cache.StateByCheckpoint(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))
if err := cache.AddCheckpointState(info1); err != nil {
t.Fatal(err)
}
state, err = cache.StateByCheckpoint(cp1)
if err != nil {
t.Fatal(err)
}
if !proto.Equal(state.InnerStateUnsafe(), info1.State.InnerStateUnsafe()) {
require.NoError(t, err)
if !proto.Equal(state.InnerStateUnsafe(), st.InnerStateUnsafe()) {
t.Error("incorrectly cached state")
}
@@ -83,31 +40,16 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
st2, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 128,
})
if err != nil {
t.Fatal(err)
}
info2 := &CheckpointState{
Checkpoint: cp2,
State: st2,
}
if err := cache.AddCheckpointState(info2); err != nil {
t.Fatal(err)
}
require.NoError(t, err)
require.NoError(t, cache.AddCheckpointState(cp2, st2))
state, err = cache.StateByCheckpoint(cp2)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(state.CloneInnerState(), info2.State.CloneInnerState()) {
t.Error("incorrectly cached state")
}
require.NoError(t, err)
assert.DeepEqual(t, st2.CloneInnerState(), state.CloneInnerState(), "incorrectly cached state")
state, err = cache.StateByCheckpoint(cp1)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(state.CloneInnerState(), info1.State.CloneInnerState()) {
t.Error("incorrectly cached state")
}
require.NoError(t, err)
assert.DeepEqual(t, st.CloneInnerState(), state.CloneInnerState(), "incorrectly cached state")
}
func TestCheckpointStateCache_MaxSize(t *testing.T) {
@@ -115,27 +57,12 @@ func TestCheckpointStateCache_MaxSize(t *testing.T) {
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 0,
})
if err != nil {
t.Fatal(err)
}
for i := uint64(0); i < maxCheckpointStateSize+100; i++ {
if err := st.SetSlot(i); err != nil {
t.Fatal(err)
}
info := &CheckpointState{
Checkpoint: &ethpb.Checkpoint{Epoch: i},
State: st,
}
if err := c.AddCheckpointState(info); err != nil {
t.Fatal(err)
}
require.NoError(t, err)
for i := uint64(0); i < uint64(maxCheckpointStateSize+100); i++ {
require.NoError(t, st.SetSlot(i))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: i, Root: make([]byte, 32)}, st))
}
if uint64(len(c.cache.ListKeys())) != maxCheckpointStateSize {
t.Errorf(
"Expected hash cache key size to be %d, got %d",
maxCheckpointStateSize,
len(c.cache.ListKeys()),
)
}
assert.Equal(t, maxCheckpointStateSize, len(c.cache.Keys()))
}

View File

@@ -1,3 +1,5 @@
// +build !libfuzzer
package cache
import (
@@ -12,14 +14,9 @@ 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, it's good to keep the old cache around for quickly switch over. 10 is a generous
// cache size as it considers 3 concurrent branches over 3 epochs.
maxCommitteesCacheSize = uint64(10)
// Due to reorgs and long finality, it's good to keep the old cache around for quickly switch over.
maxCommitteesCacheSize = uint64(32)
// CommitteeCacheMiss tracks the number of committee requests that aren't present in the cache.
CommitteeCacheMiss = promauto.NewCounter(prometheus.CounterOpts{
@@ -33,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
@@ -217,6 +205,12 @@ func (c *CommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
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) {
validatorCount := uint64(len(c.ShuffledIndices))
start := sliceutil.SplitOffset(validatorCount, c.CommitteeCount, index)

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

@@ -1,10 +1,11 @@
package cache
import (
"reflect"
"testing"
fuzz "github.com/google/gofuzz"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestCommitteeKeyFuzz_OK(t *testing.T) {
@@ -14,12 +15,8 @@ func TestCommitteeKeyFuzz_OK(t *testing.T) {
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(c)
k, err := committeeKeyFn(c)
if err != nil {
t.Fatal(err)
}
if k != key(c.Seed) {
t.Errorf("Incorrect hash k: %s, expected %s", k, key(c.Seed))
}
require.NoError(t, err)
assert.Equal(t, key(c.Seed), k)
}
}
@@ -30,17 +27,12 @@ func TestCommitteeCache_FuzzCommitteesByEpoch(t *testing.T) {
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(c)
if err := cache.AddCommitteeShuffledList(c); err != nil {
t.Fatal(err)
}
if _, err := cache.Committee(0, c.Seed, 0); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(c))
_, err := cache.Committee(0, c.Seed, 0)
require.NoError(t, err)
}
if uint64(len(cache.CommitteeCache.ListKeys())) != maxCommitteesCacheSize {
t.Error("Incorrect key size")
}
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
}
func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
@@ -50,19 +42,12 @@ func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(c)
if err := cache.AddCommitteeShuffledList(c); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(c))
indices, err := cache.ActiveIndices(c.Seed)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(indices, c.SortedIndices) {
t.Error("Saved indices not the same")
}
require.NoError(t, err)
assert.DeepEqual(t, c.SortedIndices, indices)
}
if uint64(len(cache.CommitteeCache.ListKeys())) != maxCommitteesCacheSize {
t.Error("Incorrect key size")
}
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
}

View File

@@ -2,13 +2,14 @@ package cache
import (
"math"
"reflect"
"sort"
"strconv"
"testing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestCommitteeKeyFn_OK(t *testing.T) {
@@ -19,19 +20,13 @@ func TestCommitteeKeyFn_OK(t *testing.T) {
}
k, err := committeeKeyFn(item)
if err != nil {
t.Fatal(err)
}
if k != key(item.Seed) {
t.Errorf("Incorrect hash k: %s, expected %s", k, key(item.Seed))
}
require.NoError(t, err)
assert.Equal(t, key(item.Seed), k)
}
func TestCommitteeKeyFn_InvalidObj(t *testing.T) {
_, err := committeeKeyFn("bad")
if err != ErrNotCommittee {
t.Errorf("Expected error %v, got %v", ErrNotCommittee, err)
}
assert.Equal(t, ErrNotCommittee, err)
}
func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
@@ -46,30 +41,18 @@ func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
slot := params.BeaconConfig().SlotsPerEpoch
committeeIndex := uint64(1)
indices, err := cache.Committee(slot, item.Seed, committeeIndex)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee not to exist in empty cache")
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}
wantedIndex := uint64(0)
indices, err = cache.Committee(slot, item.Seed, wantedIndex)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
start, end := startEndIndices(item, wantedIndex)
if !reflect.DeepEqual(indices, item.ShuffledIndices[start:end]) {
t.Errorf(
"Expected fetched active indices to be %v, got %v",
indices,
item.ShuffledIndices[start:end],
)
}
assert.DeepEqual(t, item.ShuffledIndices[start:end], indices)
}
func TestCommitteeCache_ActiveIndices(t *testing.T) {
@@ -77,24 +60,16 @@ func TestCommitteeCache_ActiveIndices(t *testing.T) {
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
indices, err := cache.ActiveIndices(item.Seed)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
t.Error("Expected committee not to exist in empty cache")
}
if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
indices, err = cache.ActiveIndices(item.Seed)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(indices, item.SortedIndices) {
t.Error("Did not receive correct active indices from cache")
}
require.NoError(t, err)
assert.DeepEqual(t, item.SortedIndices, indices)
}
func TestCommitteeCache_ActiveCount(t *testing.T) {
@@ -102,101 +77,69 @@ func TestCommitteeCache_ActiveCount(t *testing.T) {
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
count, err := cache.ActiveIndicesCount(item.Seed)
if err != nil {
t.Fatal(err)
}
if count != 0 {
t.Error("Expected active count not to exist in empty cache")
}
require.NoError(t, err)
assert.Equal(t, 0, count, "Expected active count not to exist in empty cache")
if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
count, err = cache.ActiveIndicesCount(item.Seed)
if err != nil {
t.Fatal(err)
}
if count != len(item.SortedIndices) {
t.Error("Did not receive correct active acount from cache")
}
require.NoError(t, err)
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)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
if err := cache.AddProposerIndicesList(seed, indices); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddProposerIndicesList(seed, indices))
received, err := cache.ProposerIndices(seed)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(indices, received) {
t.Error("Did not receive correct proposer indices from cache")
}
require.NoError(t, err)
assert.DeepEqual(t, received, indices)
item := &Committees{Seed: [32]byte{'B'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
indices, err = cache.ProposerIndices(item.Seed)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if indices != nil {
t.Error("Expected committee count not to exist in empty cache")
}
if err := cache.AddProposerIndicesList(item.Seed, indices); err != nil {
t.Fatal(err)
}
received, err = cache.ProposerIndices(item.Seed)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(indices, received) {
t.Error("Did not receive correct proposer indices from 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()
// Should rotate out all the epochs except 190 through 199.
for i := 100; i < 200; i++ {
start := 100
end := 200
for i := start; i < end; i++ {
s := []byte(strconv.Itoa(i))
item := &Committees{Seed: bytesutil.ToBytes32(s)}
if err := cache.AddCommitteeShuffledList(item); err != nil {
t.Fatal(err)
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
}
k := cache.CommitteeCache.ListKeys()
if uint64(len(k)) != maxCommitteesCacheSize {
t.Errorf("wanted: %d, got: %d", maxCommitteesCacheSize, len(k))
}
assert.Equal(t, maxCommitteesCacheSize, uint64(len(k)))
sort.Slice(k, func(i, j int) bool {
return k[i] < k[j]
})
s := bytesutil.ToBytes32([]byte(strconv.Itoa(190)))
if k[0] != key(s) {
t.Error("incorrect key received for slot 190")
}
wanted := end - int(maxCommitteesCacheSize)
s := bytesutil.ToBytes32([]byte(strconv.Itoa(wanted)))
assert.Equal(t, key(s), k[0], "incorrect key received for slot 190")
s = bytesutil.ToBytes32([]byte(strconv.Itoa(199)))
if k[len(k)-1] != key(s) {
t.Error("incorrect key received for slot 199")
}
assert.Equal(t, key(s), k[len(k)-1], "incorrect key received for slot 199")
}
func TestCommitteeCacheOutOfRange(t *testing.T) {
@@ -209,11 +152,8 @@ func TestCommitteeCacheOutOfRange(t *testing.T) {
SortedIndices: []uint64{},
ProposerIndices: []uint64{},
})
if err != nil {
t.Error(err)
}
require.NoError(t, err)
_, err = cache.Committee(0, seed, math.MaxUint64) // Overflow!
if err == nil {
t.Fatal("Did not fail as expected")
}
require.NotNil(t, err, "Did not fail as expected")
}

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

@@ -0,0 +1,16 @@
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
ProposerIndices []uint64
}

View File

@@ -13,6 +13,8 @@ go_library(
"//proto/beacon/db:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_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",
@@ -24,13 +26,17 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"deposits_test.go",
"deposits_cache_test.go",
"pending_deposits_test.go",
],
embed = [":go_default_library"],
deps = [
"//proto/beacon/db:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",

View File

@@ -17,6 +17,8 @@ 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/trieutil"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -30,9 +32,18 @@ var (
// DepositFetcher defines a struct which can retrieve deposit information from a store.
type DepositFetcher interface {
AllDeposits(ctx context.Context, beforeBlk *big.Int) []*ethpb.Deposit
AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int)
DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte)
FinalizedDeposits(ctx context.Context) *FinalizedDeposits
NonFinalizedDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
}
// FinalizedDeposits stores the trie of deposits that have been included
// in the beacon state up to the latest finalized checkpoint.
type FinalizedDeposits struct {
Deposits *trieutil.SparseMerkleTrie
MerkleTrieIndex int64
}
// DepositCache stores all in-memory deposit objects. This
@@ -41,19 +52,28 @@ 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
}
// NewDepositCache instantiates a new deposit cache
func NewDepositCache() *DepositCache {
// New instantiates a new deposit cache
func New() (*DepositCache, error) {
finalizedDepositsTrie, err := trieutil.NewTrie(int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
return nil, err
}
// 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),
}
}, nil
}
// InsertDeposit into the database. If deposit or block number are nil
@@ -91,9 +111,40 @@ func (dc *DepositCache) InsertDepositContainers(ctx context.Context, ctrs []*dbp
historicalDepositsCount.Add(float64(len(ctrs)))
}
// AllDepositContainers returns a list of deposits all historical deposit containers until the given block number.
// InsertFinalizedDeposits inserts deposits up to eth1DepositIndex (inclusive) into the finalized deposits cache.
func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1DepositIndex int64) {
ctx, span := trace.StartSpan(ctx, "DepositsCache.InsertFinalizedDeposits")
defer span.End()
dc.depositsLock.Lock()
defer dc.depositsLock.Unlock()
depositTrie := dc.finalizedDeposits.Deposits
insertIndex := dc.finalizedDeposits.MerkleTrieIndex + 1
for _, d := range dc.deposits {
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
continue
}
if d.Index > eth1DepositIndex {
break
}
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))
insertIndex++
}
dc.finalizedDeposits = &FinalizedDeposits{
Deposits: depositTrie,
MerkleTrieIndex: eth1DepositIndex,
}
}
// AllDepositContainers returns all historical deposit containers.
func (dc *DepositCache) AllDepositContainers(ctx context.Context) []*dbpb.DepositContainer {
ctx, span := trace.StartSpan(ctx, "BeaconDB.AllDepositContainers")
ctx, span := trace.StartSpan(ctx, "DepositsCache.AllDepositContainers")
defer span.End()
dc.depositsLock.RLock()
defer dc.depositsLock.RUnlock()
@@ -119,9 +170,9 @@ func (dc *DepositCache) PubkeyInChainstart(ctx context.Context, pubkey string) b
return false
}
// AllDeposits returns a list of deposits all historical deposits until the given block number
// AllDeposits returns a list of historical deposits until the given block number
// (inclusive). If no block is specified then this method returns all historical deposits.
func (dc *DepositCache) AllDeposits(ctx context.Context, beforeBlk *big.Int) []*ethpb.Deposit {
func (dc *DepositCache) AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
ctx, span := trace.StartSpan(ctx, "DepositsCache.AllDeposits")
defer span.End()
dc.depositsLock.RLock()
@@ -129,7 +180,7 @@ func (dc *DepositCache) AllDeposits(ctx context.Context, beforeBlk *big.Int) []*
var deposits []*ethpb.Deposit
for _, ctnr := range dc.deposits {
if beforeBlk == nil || beforeBlk.Uint64() >= ctnr.Eth1BlockHeight {
if untilBlk == nil || untilBlk.Uint64() >= ctnr.Eth1BlockHeight {
deposits = append(deposits, ctnr.Deposit)
}
}
@@ -171,3 +222,39 @@ func (dc *DepositCache) DepositByPubkey(ctx context.Context, pubKey []byte) (*et
}
return deposit, blockNum
}
// FinalizedDeposits returns the finalized deposits trie.
func (dc *DepositCache) FinalizedDeposits(ctx context.Context) *FinalizedDeposits {
ctx, span := trace.StartSpan(ctx, "DepositsCache.FinalizedDeposits")
defer span.End()
dc.depositsLock.RLock()
defer dc.depositsLock.RUnlock()
return &FinalizedDeposits{
Deposits: dc.finalizedDeposits.Deposits.Copy(),
MerkleTrieIndex: dc.finalizedDeposits.MerkleTrieIndex,
}
}
// NonFinalizedDeposits returns the list of non-finalized deposits until the given block number (inclusive).
// If no block is specified then this method returns all non-finalized deposits.
func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
ctx, span := trace.StartSpan(ctx, "DepositsCache.NonFinalizedDeposits")
defer span.End()
dc.depositsLock.RLock()
defer dc.depositsLock.RUnlock()
if dc.finalizedDeposits == nil {
return dc.AllDeposits(ctx, untilBlk)
}
lastFinalizedDepositIndex := dc.finalizedDeposits.MerkleTrieIndex
var deposits []*ethpb.Deposit
for _, d := range dc.deposits {
if (d.Index > lastFinalizedDepositIndex) && (untilBlk == nil || untilBlk.Uint64() >= d.Eth1BlockHeight) {
deposits = append(deposits, d.Deposit)
}
}
return deposits
}

View File

@@ -0,0 +1,575 @@
package depositcache
import (
"bytes"
"context"
"fmt"
"math/big"
"testing"
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"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/shared/trieutil"
logTest "github.com/sirupsen/logrus/hooks/test"
)
const nilDepositErr = "Ignoring nil deposit insertion"
var _ = DepositFetcher(&DepositCache{})
func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
hook := logTest.NewGlobal()
dc, err := New()
require.NoError(t, err)
dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{})
require.Equal(t, 0, len(dc.deposits), "Number of deposits changed")
assert.Equal(t, nilDepositErr, hook.LastEntry().Message)
}
func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
dc, err := New()
require.NoError(t, err)
insertions := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 3,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 4,
},
}
for _, ins := range insertions {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
}
expectedIndices := []int64{0, 1, 3, 4}
for i, ei := range expectedIndices {
assert.Equal(t, ei, dc.deposits[i].Index,
fmt.Sprintf("dc.deposits[%d].Index = %d, wanted %d", i, dc.deposits[i].Index, ei))
}
}
func TestAllDeposits_ReturnsAllDeposits(t *testing.T) {
dc, err := New()
require.NoError(t, err)
deposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
}
dc.deposits = deposits
d := dc.AllDeposits(context.Background(), nil)
assert.Equal(t, len(deposits), len(d))
}
func TestAllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
dc, err := New()
require.NoError(t, err)
deposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
}
dc.deposits = deposits
d := dc.AllDeposits(context.Background(), big.NewInt(11))
assert.Equal(t, 5, len(d))
}
func TestDepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(11))
assert.Equal(t, 5, int(n))
assert.Equal(t, bytesutil.ToBytes32([]byte("root")), root)
}
func TestDepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOldestDeposit(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(2))
assert.Equal(t, 0, int(n))
assert.Equal(t, [32]byte{}, root)
}
func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 9,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk0"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk1"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk1"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk2"), 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
},
}
pk1 := bytesutil.PadTo([]byte("pk1"), 48)
dep, blkNum := dc.DepositByPubkey(context.Background(), pk1)
if dep == nil || !bytes.Equal(dep.Data.PublicKey, pk1) {
t.Error("Returned wrong deposit")
}
assert.Equal(t, 0, blkNum.Cmp(big.NewInt(10)),
fmt.Sprintf("Returned wrong block number %v", blkNum))
}
func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
},
}
dc.deposits = append(finalizedDeposits, &dbpb.DepositContainer{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
})
dc.InsertFinalizedDeposits(context.Background(), 2)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
var deps [][]byte
for _, d := range finalizedDeposits {
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))
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 := New()
require.NoError(t, err)
oldFinalizedDeposits := []*dbpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
}
newFinalizedDeposit := dbpb.DepositContainer{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
}
dc.deposits = oldFinalizedDeposits
dc.InsertFinalizedDeposits(context.Background(), 1)
// Artificially exclude old deposits so that they can only be retrieved from previously finalized deposits.
dc.deposits = []*dbpb.DepositContainer{&newFinalizedDeposit}
dc.InsertFinalizedDeposits(context.Background(), 2)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
var deps [][]byte
for _, d := range append(oldFinalizedDeposits, &newFinalizedDeposit) {
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))
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 := New()
require.NoError(t, err)
finalizedDeposits := dc.finalizedDeposits
assert.NotNil(t, finalizedDeposits)
assert.NotNil(t, finalizedDeposits.Deposits)
assert.Equal(t, int64(-1), finalizedDeposits.MerkleTrieIndex)
}
func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
}
dc.deposits = append(finalizedDeposits,
&dbpb.DepositContainer{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
},
&dbpb.DepositContainer{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
})
dc.InsertFinalizedDeposits(context.Background(), 1)
deps := dc.NonFinalizedDeposits(context.Background(), nil)
assert.Equal(t, 2, len(deps))
}
func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *testing.T) {
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
}
dc.deposits = append(finalizedDeposits,
&dbpb.DepositContainer{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
},
&dbpb.DepositContainer{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
})
dc.InsertFinalizedDeposits(context.Background(), 1)
deps := dc.NonFinalizedDeposits(context.Background(), big.NewInt(10))
assert.Equal(t, 1, len(deps))
}

View File

@@ -1,275 +0,0 @@
package depositcache
import (
"bytes"
"context"
"math/big"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
logTest "github.com/sirupsen/logrus/hooks/test"
)
const nilDepositErr = "Ignoring nil deposit insertion"
var _ = DepositFetcher(&DepositCache{})
func TestBeaconDB_InsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
hook := logTest.NewGlobal()
dc := DepositCache{}
dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{})
if len(dc.deposits) != 0 {
t.Fatal("Number of deposits changed")
}
if hook.LastEntry().Message != nilDepositErr {
t.Errorf("Did not log correct message, wanted \"Ignoring nil deposit insertion\", got \"%s\"", hook.LastEntry().Message)
}
}
func TestBeaconDB_InsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
dc := DepositCache{}
insertions := []struct {
blkNum uint64
deposit *ethpb.Deposit
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 3,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
index: 4,
},
}
for _, ins := range insertions {
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
}
expectedIndices := []int64{0, 1, 3, 4}
for i, ei := range expectedIndices {
if dc.deposits[i].Index != ei {
t.Errorf("dc.deposits[%d].Index = %d, wanted %d", i, dc.deposits[i].Index, ei)
}
}
}
func TestBeaconDB_AllDeposits_ReturnsAllDeposits(t *testing.T) {
dc := DepositCache{}
deposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
}
dc.deposits = deposits
d := dc.AllDeposits(context.Background(), nil)
if len(d) != len(deposits) {
t.Errorf("Return the wrong number of deposits (%d) wanted %d", len(d), len(deposits))
}
}
func TestBeaconDB_AllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
dc := DepositCache{}
deposits := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
}
dc.deposits = deposits
d := dc.AllDeposits(context.Background(), big.NewInt(11))
expected := 5
if len(d) != expected {
t.Errorf("Return the wrong number of deposits (%d) wanted %d", len(d), expected)
}
}
func TestBeaconDB_DepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing.T) {
dc := DepositCache{}
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{},
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(11))
if n != 5 {
t.Errorf("Returned unexpected deposits number %d wanted %d", n, 5)
}
if root != bytesutil.ToBytes32([]byte("root")) {
t.Errorf("Returned unexpected root: %v", root)
}
}
func TestBeaconDB_DepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOldestDeposit(t *testing.T) {
dc := DepositCache{}
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{},
DepositRoot: []byte("root"),
},
}
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(2))
if n != 0 {
t.Errorf("Returned unexpected deposits number %d wanted %d", n, 0)
}
if root != [32]byte{} {
t.Errorf("Returned unexpected root: %v", root)
}
}
func TestBeaconDB_DepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
dc := DepositCache{}
dc.deposits = []*dbpb.DepositContainer{
{
Eth1BlockHeight: 9,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk0"),
},
},
},
{
Eth1BlockHeight: 10,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk1"),
},
},
},
{
Eth1BlockHeight: 11,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk1"),
},
},
},
{
Eth1BlockHeight: 12,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("pk2"),
},
},
},
}
dep, blkNum := dc.DepositByPubkey(context.Background(), []byte("pk1"))
if !bytes.Equal(dep.Data.PublicKey, []byte("pk1")) {
t.Error("Returned wrong deposit")
}
if blkNum.Cmp(big.NewInt(10)) != 0 {
t.Errorf("Returned wrong block number %v", blkNum)
}
}

View File

@@ -24,7 +24,7 @@ var (
// PendingDepositsFetcher specifically outlines a struct that can retrieve deposits
// which have not yet been included in the chain.
type PendingDepositsFetcher interface {
PendingContainers(ctx context.Context, beforeBlk *big.Int) []*dbpb.DepositContainer
PendingContainers(ctx context.Context, untilBlk *big.Int) []*dbpb.DepositContainer
}
// InsertPendingDeposit into the database. If deposit or block number are nil
@@ -50,36 +50,23 @@ func (dc *DepositCache) InsertPendingDeposit(ctx context.Context, d *ethpb.Depos
// PendingDeposits returns a list of deposits until the given block number
// (inclusive). If no block is specified then this method returns all pending
// deposits.
func (dc *DepositCache) PendingDeposits(ctx context.Context, beforeBlk *big.Int) []*ethpb.Deposit {
func (dc *DepositCache) PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
ctx, span := trace.StartSpan(ctx, "DepositsCache.PendingDeposits")
defer span.End()
dc.depositsLock.RLock()
defer dc.depositsLock.RUnlock()
var depositCntrs []*dbpb.DepositContainer
for _, ctnr := range dc.pendingDeposits {
if beforeBlk == nil || beforeBlk.Uint64() >= ctnr.Eth1BlockHeight {
depositCntrs = append(depositCntrs, ctnr)
}
}
// Sort the deposits by Merkle index.
sort.SliceStable(depositCntrs, func(i, j int) bool {
return depositCntrs[i].Index < depositCntrs[j].Index
})
depositCntrs := dc.PendingContainers(ctx, untilBlk)
var deposits []*ethpb.Deposit
for _, dep := range depositCntrs {
deposits = append(deposits, dep.Deposit)
}
span.AddAttributes(trace.Int64Attribute("count", int64(len(deposits))))
return deposits
}
// PendingContainers returns a list of deposit containers until the given block number
// (inclusive).
func (dc *DepositCache) PendingContainers(ctx context.Context, beforeBlk *big.Int) []*dbpb.DepositContainer {
func (dc *DepositCache) PendingContainers(ctx context.Context, untilBlk *big.Int) []*dbpb.DepositContainer {
ctx, span := trace.StartSpan(ctx, "DepositsCache.PendingDeposits")
defer span.End()
dc.depositsLock.RLock()
@@ -87,7 +74,7 @@ func (dc *DepositCache) PendingContainers(ctx context.Context, beforeBlk *big.In
var depositCntrs []*dbpb.DepositContainer
for _, ctnr := range dc.pendingDeposits {
if beforeBlk == nil || beforeBlk.Uint64() >= ctnr.Eth1BlockHeight {
if untilBlk == nil || untilBlk.Uint64() >= ctnr.Eth1BlockHeight {
depositCntrs = append(depositCntrs, ctnr)
}
}
@@ -141,7 +128,7 @@ func (dc *DepositCache) RemovePendingDeposit(ctx context.Context, d *ethpb.Depos
}
// PrunePendingDeposits removes any deposit which is older than the given deposit merkle tree index.
func (dc *DepositCache) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int) {
func (dc *DepositCache) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64) {
ctx, span := trace.StartSpan(ctx, "DepositsCache.PrunePendingDeposits")
defer span.End()
@@ -155,7 +142,7 @@ func (dc *DepositCache) PrunePendingDeposits(ctx context.Context, merkleTreeInde
var cleanDeposits []*dbpb.DepositContainer
for _, dp := range dc.pendingDeposits {
if dp.Index >= int64(merkleTreeIndex) {
if dp.Index >= merkleTreeIndex {
cleanDeposits = append(cleanDeposits, dp)
}
}

View File

@@ -3,13 +3,14 @@ package depositcache
import (
"context"
"math/big"
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
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{})
@@ -18,28 +19,38 @@ func TestInsertPendingDeposit_OK(t *testing.T) {
dc := DepositCache{}
dc.InsertPendingDeposit(context.Background(), &ethpb.Deposit{}, 111, 100, [32]byte{})
if len(dc.pendingDeposits) != 1 {
t.Error("Deposit not inserted")
}
assert.Equal(t, 1, len(dc.pendingDeposits), "Deposit not inserted")
}
func TestInsertPendingDeposit_ignoresNilDeposit(t *testing.T) {
dc := DepositCache{}
dc.InsertPendingDeposit(context.Background(), nil /*deposit*/, 0 /*blockNum*/, 0, [32]byte{})
if len(dc.pendingDeposits) > 0 {
t.Error("Unexpected deposit insertion")
assert.Equal(t, 0, len(dc.pendingDeposits))
}
func makeDepositProof() [][]byte {
proof := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
for i := range proof {
proof[i] = make([]byte, 32)
}
return proof
}
func TestRemovePendingDeposit_OK(t *testing.T) {
db := DepositCache{}
proof1 := make([][]byte, 33)
proof1 := makeDepositProof()
proof1[0] = bytesutil.PadTo([]byte{'A'}, 32)
proof2 := make([][]byte, 33)
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},
@@ -55,21 +66,23 @@ func TestRemovePendingDeposit_IgnoresNilDeposit(t *testing.T) {
dc := DepositCache{}
dc.pendingDeposits = []*dbpb.DepositContainer{{Deposit: &ethpb.Deposit{}}}
dc.RemovePendingDeposit(context.Background(), nil /*deposit*/)
if len(dc.pendingDeposits) != 1 {
t.Errorf("Deposit unexpectedly removed")
}
assert.Equal(t, 1, len(dc.pendingDeposits), "Deposit unexpectedly removed")
}
func TestPendingDeposit_RoundTrip(t *testing.T) {
dc := DepositCache{}
proof := make([][]byte, 33)
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)
if len(dc.pendingDeposits) != 0 {
t.Error("Failed to insert & delete a pending deposit")
}
assert.Equal(t, 0, len(dc.pendingDeposits), "Failed to insert & delete a pending deposit")
}
func TestPendingDeposits_OK(t *testing.T) {
@@ -86,15 +99,10 @@ func TestPendingDeposits_OK(t *testing.T) {
{Proof: [][]byte{[]byte("A")}},
{Proof: [][]byte{[]byte("B")}},
}
if !reflect.DeepEqual(deposits, expected) {
t.Errorf("Unexpected deposits. got=%+v want=%+v", deposits, expected)
}
assert.DeepEqual(t, expected, deposits)
all := dc.PendingDeposits(context.Background(), nil)
if len(all) != len(dc.pendingDeposits) {
t.Error("PendingDeposits(ctx, nil) did not return all deposits")
}
assert.Equal(t, len(dc.pendingDeposits), len(all), "PendingDeposits(ctx, nil) did not return all deposits")
}
func TestPrunePendingDeposits_ZeroMerkleIndex(t *testing.T) {
@@ -118,9 +126,7 @@ func TestPrunePendingDeposits_ZeroMerkleIndex(t *testing.T) {
{Eth1BlockHeight: 10, Index: 10},
{Eth1BlockHeight: 12, Index: 12},
}
if !reflect.DeepEqual(dc.pendingDeposits, expected) {
t.Errorf("Unexpected deposits. got=%+v want=%+v", dc.pendingDeposits, expected)
}
assert.DeepEqual(t, expected, dc.pendingDeposits)
}
func TestPrunePendingDeposits_OK(t *testing.T) {
@@ -143,9 +149,7 @@ func TestPrunePendingDeposits_OK(t *testing.T) {
{Eth1BlockHeight: 12, Index: 12},
}
if !reflect.DeepEqual(dc.pendingDeposits, expected) {
t.Errorf("Unexpected deposits. got=%+v want=%+v", dc.pendingDeposits, expected)
}
assert.DeepEqual(t, expected, dc.pendingDeposits)
dc.pendingDeposits = []*dbpb.DepositContainer{
{Eth1BlockHeight: 2, Index: 2},
@@ -162,8 +166,5 @@ func TestPrunePendingDeposits_OK(t *testing.T) {
{Eth1BlockHeight: 12, Index: 12},
}
if !reflect.DeepEqual(dc.pendingDeposits, expected) {
t.Errorf("Unexpected deposits. got=%+v want=%+v", dc.pendingDeposits, expected)
}
assert.DeepEqual(t, expected, dc.pendingDeposits)
}

View File

@@ -1,46 +1,34 @@
package cache_test
import (
"reflect"
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestHotStateCache_RoundTrip(t *testing.T) {
c := cache.NewHotStateCache()
root := [32]byte{'A'}
state := c.Get(root)
if state != nil {
t.Errorf("Empty cache returned an object: %v", state)
}
if c.Has(root) {
t.Error("Empty cache has an object")
}
assert.Equal(t, (*stateTrie.BeaconState)(nil), state)
assert.Equal(t, false, c.Has(root), "Empty cache has an object")
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
if err != nil {
t.Fatal(err)
}
c.Put(root, state)
require.NoError(t, err)
c.Put(root, state)
assert.Equal(t, true, c.Has(root), "Empty cache does not have an object")
if !c.Has(root) {
t.Error("Empty cache does not have an object")
}
res := c.Get(root)
if state == nil {
t.Errorf("Empty cache returned an object: %v", state)
}
if !reflect.DeepEqual(state.CloneInnerState(), res.CloneInnerState()) {
t.Error("Expected equal protos to return from cache")
}
assert.NotNil(t, state)
assert.DeepEqual(t, res.CloneInnerState(), state.CloneInnerState(), "Expected equal protos to return from cache")
c.Delete(root)
if c.Has(root) {
t.Error("Cache not suppose to have the object")
}
assert.Equal(t, false, c.Has(root), "Cache not supposed to have the object")
}

View File

@@ -2,12 +2,13 @@ package cache_test
import (
"context"
"reflect"
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestSkipSlotCache_RoundTrip(t *testing.T) {
@@ -15,39 +16,20 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
c := cache.NewSkipSlotCache()
state, err := c.Get(ctx, 5)
if err != nil {
t.Error(err)
}
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Empty cache returned an object")
if state != nil {
t.Errorf("Empty cache returned an object: %v", state)
}
if err := c.MarkInProgress(5); err != nil {
t.Error(err)
}
require.NoError(t, c.MarkInProgress(5))
state, err = stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if err = c.Put(ctx, 5, state); err != nil {
t.Error(err)
}
if err := c.MarkNotInProgress(5); err != nil {
t.Error(err)
}
require.NoError(t, c.Put(ctx, 5, state))
require.NoError(t, c.MarkNotInProgress(5))
res, err := c.Get(ctx, 5)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(state.CloneInnerState(), res.CloneInnerState()) {
t.Error("Expected equal protos to return from cache")
}
require.NoError(t, err)
assert.DeepEqual(t, res.CloneInnerState(), state.CloneInnerState(), "Expected equal protos to return from cache")
}

View File

@@ -1,58 +1,44 @@
package cache
import (
"reflect"
"testing"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestSubnetIDsCache_RoundTrip(t *testing.T) {
c := newSubnetIDs()
slot := uint64(100)
committeeIDs := c.GetAggregatorSubnetIDs(slot)
if len(committeeIDs) != 0 {
t.Errorf("Empty cache returned an object: %v", committeeIDs)
}
assert.Equal(t, 0, len(committeeIDs), "Empty cache returned an object")
c.AddAggregatorSubnetID(slot, 1)
res := c.GetAggregatorSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{1}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{1}, res)
c.AddAggregatorSubnetID(slot, 2)
res = c.GetAggregatorSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{1, 2}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{1, 2}, res)
c.AddAggregatorSubnetID(slot, 3)
res = c.GetAggregatorSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{1, 2, 3}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{1, 2, 3}, res)
committeeIDs = c.GetAttesterSubnetIDs(slot)
if len(committeeIDs) != 0 {
t.Errorf("Empty cache returned an object: %v", committeeIDs)
}
assert.Equal(t, 0, len(committeeIDs), "Empty cache returned an object")
c.AddAttesterSubnetID(slot, 11)
res = c.GetAttesterSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{11}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{11}, res)
c.AddAttesterSubnetID(slot, 22)
res = c.GetAttesterSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{11, 22}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{11, 22}, res)
c.AddAttesterSubnetID(slot, 33)
res = c.GetAttesterSubnetIDs(slot)
if !reflect.DeepEqual(res, []uint64{11, 22, 33}) {
t.Error("Expected equal value to return from cache")
}
assert.DeepEqual(t, []uint64{11, 22, 33}, res)
}
func TestSubnetIDsCache_PersistentCommitteeRoundtrip(t *testing.T) {
@@ -73,12 +59,8 @@ func TestSubnetIDsCache_PersistentCommitteeRoundtrip(t *testing.T) {
t.Errorf("Couldn't find entry in cache for pubkey %#x", pubkey)
continue
}
if idxs[0] != i {
t.Fatalf("Wanted index of %d but got %d", i, idxs[0])
}
require.Equal(t, i, idxs[0])
}
coms := c.GetAllSubnets()
if len(coms) != 20 {
t.Errorf("Number of committees is not %d but is %d", 20, len(coms))
}
assert.Equal(t, 20, len(coms))
}

View File

@@ -4,8 +4,17 @@ load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_library(
name = "go_default_library",
srcs = [
"block.go",
"block_operations.go",
"attestation.go",
"attester_slashing.go",
"deposit.go",
"eth1_data.go",
"exit.go",
"genesis.go",
"header.go",
"log.go",
"proposer_slashing.go",
"randao.go",
"signature.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks",
visibility = [
@@ -17,11 +26,11 @@ go_library(
"//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",
"//shared/bytesutil:go_default_library",
"//shared/depositutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
@@ -40,17 +49,23 @@ go_test(
name = "go_default_test",
size = "medium",
srcs = [
"attestation_test.go",
"attester_slashing_test.go",
"block_operations_fuzz_test.go",
"block_operations_test.go",
"block_regression_test.go",
"block_test.go",
"deposit_test.go",
"eth1_data_test.go",
"exit_test.go",
"genesis_test.go",
"header_test.go",
"proposer_slashing_test.go",
"randao_test.go",
],
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",
@@ -59,13 +74,13 @@ go_test(
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
],
)

View File

@@ -0,0 +1,379 @@
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"
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"
)
// ProcessAttestations applies processing operations to a block's inner attestation
// records.
func ProcessAttestations(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
var err error
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)
}
}
return beaconState, nil
}
// ProcessAttestation verifies an input attestation can pass through processing using the given beacon state.
//
// Spec pseudocode definition:
// def process_attestation(state: BeaconState, attestation: Attestation) -> None:
// data = attestation.data
// assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state))
// assert data.target.epoch == compute_epoch_at_slot(data.slot)
// assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= data.slot + SLOTS_PER_EPOCH
// assert data.index < get_committee_count_per_slot(state, data.target.epoch)
//
// committee = get_beacon_committee(state, data.slot, data.index)
// assert len(attestation.aggregation_bits) == len(committee)
//
// pending_attestation = PendingAttestation(
// data=data,
// aggregation_bits=attestation.aggregation_bits,
// inclusion_delay=state.slot - data.slot,
// proposer_index=get_beacon_proposer_index(state),
// )
//
// if data.target.epoch == get_current_epoch(state):
// assert data.source == state.current_justified_checkpoint
// state.current_epoch_attestations.append(pending_attestation)
// else:
// assert data.source == state.previous_justified_checkpoint
// state.previous_epoch_attestations.append(pending_attestation)
//
// # Check signature
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
func ProcessAttestation(
ctx context.Context,
beaconState *stateTrie.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
beaconState, err := ProcessAttestationNoVerifySignature(ctx, beaconState, att)
if err != nil {
return nil, err
}
return beaconState, VerifyAttestationSignature(ctx, beaconState, att)
}
// 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 ProcessAttestationsNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
var err error
for idx, attestation := range body.Attestations {
beaconState, err = ProcessAttestationNoVerifySignature(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
}
}
return beaconState, nil
}
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
defer span.End()
if att == nil || att.Data == nil || att.Data.Target == nil {
return nil, errors.New("nil attestation data target")
}
currEpoch := helpers.SlotToEpoch(beaconState.Slot())
var prevEpoch uint64
if currEpoch == 0 {
prevEpoch = 0
} else {
prevEpoch = currEpoch - 1
}
data := att.Data
if data.Target.Epoch != prevEpoch && data.Target.Epoch != currEpoch {
return nil, fmt.Errorf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
data.Target.Epoch,
prevEpoch,
currEpoch,
)
}
if helpers.SlotToEpoch(data.Slot) != data.Target.Epoch {
return nil, fmt.Errorf("data slot is not in the same epoch as target %d != %d", helpers.SlotToEpoch(data.Slot), data.Target.Epoch)
}
s := att.Data.Slot
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
if !minInclusionCheck {
return nil, fmt.Errorf(
"attestation slot %d + inclusion delay %d > state slot %d",
s,
params.BeaconConfig().MinAttestationInclusionDelay,
beaconState.Slot(),
)
}
if !epochInclusionCheck {
return nil, fmt.Errorf(
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
beaconState.Slot(),
s,
params.BeaconConfig().SlotsPerEpoch,
)
}
activeValidatorCount, err := helpers.ActiveValidatorCount(beaconState, att.Data.Target.Epoch)
if err != nil {
return nil, err
}
c := helpers.SlotCommitteeCount(activeValidatorCount)
if att.Data.CommitteeIndex > c {
return nil, fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
}
if err := helpers.VerifyAttestationBitfieldLengths(beaconState, att); err != nil {
return nil, errors.Wrap(err, "could not verify attestation bitfields")
}
proposerIndex, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, err
}
pendingAtt := &pb.PendingAttestation{
Data: data,
AggregationBits: att.AggregationBits,
InclusionDelay: beaconState.Slot() - s,
ProposerIndex: proposerIndex,
}
var ffgSourceEpoch uint64
var ffgSourceRoot []byte
var ffgTargetEpoch uint64
if data.Target.Epoch == currEpoch {
ffgSourceEpoch = beaconState.CurrentJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.CurrentJustifiedCheckpoint().Root
ffgTargetEpoch = currEpoch
if err := beaconState.AppendCurrentEpochAttestations(pendingAtt); err != nil {
return nil, err
}
} else {
ffgSourceEpoch = beaconState.PreviousJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.PreviousJustifiedCheckpoint().Root
ffgTargetEpoch = prevEpoch
if err := beaconState.AppendPreviousEpochAttestations(pendingAtt); err != nil {
return nil, err
}
}
if data.Source.Epoch != ffgSourceEpoch {
return nil, fmt.Errorf("expected source epoch %d, received %d", ffgSourceEpoch, data.Source.Epoch)
}
if !bytes.Equal(data.Source.Root, ffgSourceRoot) {
return nil, fmt.Errorf("expected source root %#x, received %#x", ffgSourceRoot, data.Source.Root)
}
if data.Target.Epoch != ffgTargetEpoch {
return nil, fmt.Errorf("expected target epoch %d, received %d", ffgTargetEpoch, data.Target.Epoch)
}
// Verify attesting indices are correct.
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return nil, err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return nil, err
}
return beaconState, nil
}
// VerifyAttestationsSignatures will verify the signatures of the provided attestations. This method performs
// a single BLS verification call to verify the signatures of all of the provided attestations. All
// of the provided attestations must have valid signatures or this method will return an error.
// This method does not determine which attestation signature is invalid, only that one or more
// attestation signatures were not valid.
func VerifyAttestationsSignatures(ctx context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationsSignatures")
defer span.End()
atts := b.Block.Body.Attestations
span.AddAttributes(trace.Int64Attribute("attestations", int64(len(atts))))
if len(atts) == 0 {
return nil
}
fork := beaconState.Fork()
gvr := beaconState.GenesisValidatorRoot()
dt := params.BeaconConfig().DomainBeaconAttester
// Split attestations by fork. Note: the signature domain will differ based on the fork.
var preForkAtts []*ethpb.Attestation
var postForkAtts []*ethpb.Attestation
for _, a := range atts {
if helpers.SlotToEpoch(a.Data.Slot) < fork.Epoch {
preForkAtts = append(preForkAtts, a)
} else {
postForkAtts = append(postForkAtts, a)
}
}
// Check attestations from before the fork.
if fork.Epoch > 0 { // Check to prevent underflow.
prevDomain, err := helpers.Domain(fork, fork.Epoch-1, dt, gvr)
if err != nil {
return err
}
if err := verifyAttestationsSigWithDomain(ctx, beaconState, preForkAtts, prevDomain); err != nil {
return err
}
} else if len(preForkAtts) > 0 {
// This is a sanity check that preForkAtts were not ignored when fork.Epoch == 0. This
// condition is not possible, but it doesn't hurt to check anyway.
return errors.New("some attestations were not verified from previous fork before genesis")
}
// Then check attestations from after the fork.
currDomain, err := helpers.Domain(fork, fork.Epoch, dt, gvr)
if err != nil {
return err
}
return verifyAttestationsSigWithDomain(ctx, beaconState, postForkAtts, currDomain)
}
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
// the signature in that attestation.
func VerifyAttestationSignature(ctx context.Context, beaconState *stateTrie.BeaconState, att *ethpb.Attestation) error {
if att == nil || att.Data == nil || att.AggregationBits.Count() == 0 {
return fmt.Errorf("nil or missing attestation data: %v", att)
}
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
return VerifyIndexedAttestation(ctx, beaconState, indexedAtt)
}
// VerifyIndexedAttestation determines the validity of an indexed attestation.
//
// Spec pseudocode definition:
// def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: IndexedAttestation) -> bool:
// """
// Check if ``indexed_attestation`` is not empty, has sorted and unique indices and has a valid aggregate signature.
// """
// # Verify indices are sorted and unique
// indices = indexed_attestation.attesting_indices
// if len(indices) == 0 or not indices == sorted(set(indices)):
// return False
// # Verify aggregate signature
// pubkeys = [state.validators[i].pubkey for i in indices]
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
// signing_root = compute_signing_root(indexed_attestation.data, domain)
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.BeaconState, indexedAtt *ethpb.IndexedAttestation) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyIndexedAttestation")
defer span.End()
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
domain, err := helpers.Domain(beaconState.Fork(), indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
if err != nil {
return err
}
indices := indexedAtt.AttestingIndices
pubkeys := []bls.PublicKey{}
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(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)
}
// Inner method to verify attestations. This abstraction allows for the domain to be provided as an
// argument.
func verifyAttestationsSigWithDomain(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) error {
if len(atts) == 0 {
return nil
}
set, err := createAttestationSignatureSet(ctx, beaconState, atts, domain)
if err != nil {
return err
}
verify, err := set.Verify()
if err != nil {
return errors.Errorf("got error in multiple verification: %v", err)
}
if !verify {
return errors.New("one or more attestation signatures did not verify")
}
return nil
}
// VerifyAttSigUseCheckPt uses the checkpoint info object to verify attestation signature.
func VerifyAttSigUseCheckPt(ctx context.Context, c *pb.CheckPtInfo, att *ethpb.Attestation) error {
if att == nil || att.Data == nil || att.AggregationBits.Count() == 0 {
return fmt.Errorf("nil or missing attestation data: %v", att)
}
seed := bytesutil.ToBytes32(c.Seed)
committee, err := helpers.BeaconCommittee(c.ActiveIndices, seed, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt := attestationutil.ConvertToIndexed(ctx, att, committee)
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
domain, err := helpers.Domain(c.Fork, indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, c.GenesisRoot)
if err != nil {
return err
}
indices := indexedAtt.AttestingIndices
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,894 @@
package blocks_test
import (
"context"
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/aggregation"
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"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Slot: 5,
},
},
}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
}
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
want := fmt.Sprintf(
"attestation slot %d + inclusion delay %d > state slot %d",
attestations[0].Data.Slot,
params.BeaconConfig().MinAttestationInclusionDelay,
beaconState.Slot(),
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0}}}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{att},
},
}
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch*4 + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
att.Data.Target.Epoch,
helpers.PrevEpoch(beaconState),
helpers.CurrentEpoch(beaconState),
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
aggBits := bitfield.NewBitlist(3)
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
},
}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
}
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
require.NoError(t, beaconState.SetSlot(beaconState.Slot()+params.BeaconConfig().MinAttestationInclusionDelay))
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.CurrentEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
want = fmt.Sprintf(
"expected source root %#x, received %#x",
beaconState.CurrentJustifiedCheckpoint().Root,
attestations[0].Data.Source.Root,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Slot: params.BeaconConfig().SlotsPerEpoch,
},
AggregationBits: aggBits,
},
}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: attestations,
},
}
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.PrevEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.CurrentEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
want = fmt.Sprintf(
"expected source root %#x, received %#x",
beaconState.CurrentJustifiedCheckpoint().Root,
attestations[0].Data.Source.Root,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(4)
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0}},
AggregationBits: aggBits,
}
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Attestations: []*ethpb.Attestation{att},
},
}
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
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, b)
assert.ErrorContains(t, expected, err)
}
func TestProcessAttestations_OK(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
},
AggregationBits: aggBits,
Signature: make([]byte, 96),
}
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices := attestationutil.AttestingIndices(att.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
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)
assert.NoError(t, err)
}
func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
data := &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
BeaconBlockRoot: make([]byte, 32),
}
aggBits1 := bitfield.NewBitlist(4)
aggBits1.SetBitAt(0, true)
aggBits1.SetBitAt(1, true)
aggBits1.SetBitAt(2, true)
att1 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits1,
}
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = bytesutil.PadTo([]byte("hello-world"), 32)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices1 := attestationutil.AttestingIndices(att1.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices1))
for i, indice := range attestingIndices1 {
sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att1.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
aggBits2 := bitfield.NewBitlist(4)
aggBits2.SetBitAt(1, true)
aggBits2.SetBitAt(2, true)
aggBits2.SetBitAt(3, true)
att2 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits2,
}
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices2 := attestationutil.AttestingIndices(att2.AggregationBits, committee)
require.NoError(t, err)
sigs = make([]bls.Signature, len(attestingIndices2))
for i, indice := range attestingIndices2 {
sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att2.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
_, err = attaggregation.AggregatePair(att1, att2)
assert.ErrorContains(t, aggregation.ErrBitsOverlap.Error(), err)
}
func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 300)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
data := &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
BeaconBlockRoot: make([]byte, 32),
}
aggBits1 := bitfield.NewBitlist(9)
aggBits1.SetBitAt(0, true)
aggBits1.SetBitAt(1, true)
att1 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits1,
Signature: make([]byte, 32),
}
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices1 := attestationutil.AttestingIndices(att1.AggregationBits, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices1))
for i, indice := range attestingIndices1 {
sb, err := helpers.ComputeDomainAndSign(beaconState, 0, data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
aggBits2 := bitfield.NewBitlist(9)
aggBits2.SetBitAt(2, true)
aggBits2.SetBitAt(3, true)
att2 := &ethpb.Attestation{
Data: data,
AggregationBits: aggBits2,
Signature: make([]byte, 32),
}
committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices2 := attestationutil.AttestingIndices(att2.AggregationBits, committee)
require.NoError(t, err)
sigs = make([]bls.Signature, len(attestingIndices2))
for i, indice := range attestingIndices2 {
sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att2.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
aggregatedAtt, err := attaggregation.AggregatePair(att1, att2)
require.NoError(t, err)
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)
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 1)
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Slot: params.BeaconConfig().SlotsPerEpoch,
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
}
wanted := fmt.Sprintf("data slot is not in the same epoch as target %d != %d", helpers.SlotToEpoch(att.Data.Slot), att.Data.Target.Epoch)
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.ErrorContains(t, wanted, err)
}
func TestProcessAttestationsNoVerify_OK(t *testing.T) {
// Attestation with an empty signature
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err = blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
CommitteeIndex: 100,
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
require.NoError(t, beaconState.SetSlot(beaconState.Slot()+params.BeaconConfig().MinAttestationInclusionDelay))
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.ErrorContains(t, "committee index 100 >= committee count 1", err)
}
func TestConvertToIndexed_OK(t *testing.T) {
helpers.ClearCache()
validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
tests := []struct {
aggregationBitfield bitfield.Bitlist
wantedAttestingIndices []uint64
}{
{
aggregationBitfield: bitfield.Bitlist{0x07},
wantedAttestingIndices: []uint64{43, 47},
},
{
aggregationBitfield: bitfield.Bitlist{0x03},
wantedAttestingIndices: []uint64{47},
},
{
aggregationBitfield: bitfield.Bitlist{0x01},
wantedAttestingIndices: []uint64{},
},
}
var sig [96]byte
copy(sig[:], "signed")
attestation := &ethpb.Attestation{
Signature: sig[:],
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
}
for _, tt := range tests {
attestation.AggregationBits = tt.aggregationBitfield
wanted := &ethpb.IndexedAttestation{
AttestingIndices: tt.wantedAttestingIndices,
Data: attestation.Data,
Signature: attestation.Signature,
}
committee, err := helpers.BeaconCommitteeFromState(state, attestation.Data.Slot, attestation.Data.CommitteeIndex)
require.NoError(t, err)
ia := attestationutil.ConvertToIndexed(context.Background(), attestation, committee)
assert.DeepEqual(t, wanted, ia, "Convert attestation to indexed attestation didn't result as wanted")
}
}
func TestVerifyIndexedAttestation_OK(t *testing.T) {
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
state, 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),
})
require.NoError(t, err)
tests := []struct {
attestation *ethpb.IndexedAttestation
}{
{attestation: &ethpb.IndexedAttestation{
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),
}},
}
for _, tt := range tests {
var sig []bls.Signature
for _, idx := range tt.attestation.AttestingIndices {
sb, err := helpers.ComputeDomainAndSign(state, tt.attestation.Data.Target.Epoch, tt.attestation.Data, params.BeaconConfig().DomainBeaconAttester, keys[idx])
require.NoError(t, err)
validatorSig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sig = append(sig, validatorSig)
}
aggSig := bls.AggregateSignatures(sig)
marshalledSig := aggSig.Marshal()
tt.attestation.Signature = marshalledSig
err = blocks.VerifyIndexedAttestation(context.Background(), state, tt.attestation)
assert.NoError(t, err, "Failed to verify indexed attestation")
}
}
func TestValidateIndexedAttestation_AboveMaxLength(t *testing.T) {
indexedAtt1 := &ethpb.IndexedAttestation{
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+5),
}
for i := uint64(0); i < params.BeaconConfig().MaxValidatorsPerCommittee+5; i++ {
indexedAtt1.AttestingIndices[i] = i
indexedAtt1.Data = &ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: i,
},
}
}
want := "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE"
err := blocks.VerifyIndexedAttestation(context.Background(), &stateTrie.BeaconState{}, indexedAtt1)
assert.ErrorContains(t, want, err)
}
func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
beaconState, keys := testutil.DeterministicGenesisState(t, 1000)
sig := keys[0].Sign([]byte{'t', 'e', 's', 't'})
list := bitfield.Bitlist{0b11111111}
atts := []*ethpb.Attestation{}
for i := uint64(0); i < 1000; i++ {
atts = append(atts, &ethpb.Attestation{
Data: &ethpb.AttestationData{
CommitteeIndex: 1,
Slot: 1,
},
Signature: sig.Marshal(),
AggregationBits: list,
})
}
want := "nil or missing indexed attestation data"
_, err := blocks.AttestationSignatureSet(context.Background(), beaconState, atts)
assert.ErrorContains(t, want, err)
atts = []*ethpb.Attestation{}
list = bitfield.Bitlist{0b00000000}
for i := uint64(0); i < 1000; i++ {
atts = append(atts, &ethpb.Attestation{
Data: &ethpb.AttestationData{
CommitteeIndex: 1,
Slot: 1,
Target: &ethpb.Checkpoint{
Root: []byte{},
},
},
Signature: sig.Marshal(),
AggregationBits: list,
})
}
want = "expected non-empty attesting indices"
_, err = blocks.AttestationSignatureSet(context.Background(), beaconState, atts)
assert.ErrorContains(t, want, err)
}
func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st := testutil.NewBeaconState()
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
// In this test, att1 is from the prior fork and att2 is from the new fork.
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st := testutil.NewBeaconState()
require.NoError(t, st.SetSlot(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,
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
prevDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch-1, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, prevDomain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1*params.BeaconConfig().SlotsPerEpoch+1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1*params.BeaconConfig().SlotsPerEpoch + 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
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
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st := testutil.NewBeaconState()
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 0,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := &ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
BeaconBlockRoot: make([]byte, 32),
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
},
Signature: make([]byte, 96),
}
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureSet(ctx, st, []*ethpb.Attestation{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
}

View File

@@ -0,0 +1,134 @@
package blocks
import (
"context"
"sort"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
// ProcessAttesterSlashings is one of the operations performed
// on each processed beacon block to slash attesters based on
// Casper FFG slashing conditions if any slashable events occurred.
//
// Spec pseudocode definition:
// def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSlashing) -> None:
// attestation_1 = attester_slashing.attestation_1
// attestation_2 = attester_slashing.attestation_2
// assert is_slashable_attestation_data(attestation_1.data, attestation_2.data)
// assert is_valid_indexed_attestation(state, attestation_1)
// assert is_valid_indexed_attestation(state, attestation_2)
//
// slashed_any = False
// indices = set(attestation_1.attesting_indices).intersection(attestation_2.attesting_indices)
// for index in sorted(indices):
// if is_slashable_validator(state.validators[index], get_current_epoch(state)):
// slash_validator(state, index)
// slashed_any = True
// assert slashed_any
func ProcessAttesterSlashings(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
for idx, slashing := range body.AttesterSlashings {
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, errors.Wrapf(err, "could not verify attester slashing %d", idx)
}
slashableIndices := slashableAttesterIndices(slashing)
sort.SliceStable(slashableIndices, func(i, j int) bool {
return slashableIndices[i] < slashableIndices[j]
})
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
var err error
var slashedAny bool
var val *stateTrie.ReadOnlyValidator
for _, validatorIndex := range slashableIndices {
val, err = beaconState.ValidatorAtIndexReadOnly(validatorIndex)
if err != nil {
return nil, err
}
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
beaconState, err = v.SlashValidator(beaconState, validatorIndex)
if err != nil {
return nil, errors.Wrapf(err, "could not slash validator index %d",
validatorIndex)
}
slashedAny = true
}
}
if !slashedAny {
return nil, errors.New("unable to slash any validator despite confirmed attester slashing")
}
}
return beaconState, nil
}
// VerifyAttesterSlashing validates the attestation data in both attestations in the slashing object.
func VerifyAttesterSlashing(ctx context.Context, beaconState *stateTrie.BeaconState, slashing *ethpb.AttesterSlashing) error {
if slashing == nil {
return errors.New("nil slashing")
}
if slashing.Attestation_1 == nil || slashing.Attestation_2 == nil {
return errors.New("nil attestation")
}
if slashing.Attestation_1.Data == nil || slashing.Attestation_2.Data == nil {
return errors.New("nil attestation data")
}
att1 := slashing.Attestation_1
att2 := slashing.Attestation_2
data1 := att1.Data
data2 := att2.Data
if !IsSlashableAttestationData(data1, data2) {
return errors.New("attestations are not slashable")
}
if err := VerifyIndexedAttestation(ctx, beaconState, att1); err != nil {
return errors.Wrap(err, "could not validate indexed attestation")
}
if err := VerifyIndexedAttestation(ctx, beaconState, att2); err != nil {
return errors.Wrap(err, "could not validate indexed attestation")
}
return nil
}
// IsSlashableAttestationData verifies a slashing against the Casper Proof of Stake FFG rules.
//
// Spec pseudocode definition:
// def is_slashable_attestation_data(data_1: AttestationData, data_2: AttestationData) -> bool:
// """
// Check if ``data_1`` and ``data_2`` are slashable according to Casper FFG rules.
// """
// return (
// # Double vote
// (data_1 != data_2 and data_1.target.epoch == data_2.target.epoch) or
// # 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 {
if data1 == nil || data2 == nil || data1.Target == nil || data2.Target == nil || data1.Source == nil || data2.Source == nil {
return false
}
isDoubleVote := !attestationutil.AttDataIsEqual(data1, data2) && data1.Target.Epoch == data2.Target.Epoch
isSurroundVote := data1.Source.Epoch < data2.Source.Epoch && data2.Target.Epoch < data1.Target.Epoch
return isDoubleVote || isSurroundVote
}
func slashableAttesterIndices(slashing *ethpb.AttesterSlashing) []uint64 {
if slashing == nil || slashing.Attestation_1 == nil || slashing.Attestation_2 == nil {
return nil
}
indices1 := slashing.Attestation_1.AttestingIndices
indices2 := slashing.Attestation_2.AttestingIndices
return sliceutil.IntersectionUint64(indices1, indices2)
}

View File

@@ -0,0 +1,195 @@
package blocks_test
import (
"context"
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"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"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestSlashableAttestationData_CanSlash(t *testing.T) {
att1 := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
BeaconBlockRoot: make([]byte, 32),
}
att2 := &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'B'}, 32)},
BeaconBlockRoot: make([]byte, 32),
}
assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable")
att1.Target.Epoch = 4
att1.Source.Epoch = 2
att2.Source.Epoch = 3
assert.Equal(t, true, blocks.IsSlashableAttestationData(att1, att2), "Atts should have been slashable")
}
func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
slashings := []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
Signature: make([]byte, 96),
},
Attestation_2: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
Signature: make([]byte, 96),
},
},
}
registry := []*ethpb.Validator{}
currentSlot := uint64(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
require.NoError(t, err)
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, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T) {
registry := []*ethpb.Validator{}
currentSlot := uint64(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
require.NoError(t, err)
slashings := []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
Attestation_2: &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+1),
Signature: make([]byte, 96),
},
},
}
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, b)
assert.ErrorContains(t, want, err)
}
func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
for _, vv := range beaconState.Validators() {
vv.WithdrawableEpoch = 1 * params.BeaconConfig().SlotsPerEpoch
}
att1 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: []uint64{0, 1},
}
domain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
require.NoError(t, err)
signingRoot, err := helpers.ComputeSigningRoot(att1.Data, domain)
assert.NoError(t, err, "Could not get signing root of beacon block header")
sig0 := privKeys[0].Sign(signingRoot[:])
sig1 := privKeys[1].Sign(signingRoot[:])
aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1})
att1.Signature = aggregateSig.Marshal()
att2 := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
BeaconBlockRoot: make([]byte, 32),
},
AttestingIndices: []uint64{0, 1},
}
signingRoot, err = helpers.ComputeSigningRoot(att2.Data, domain)
assert.NoError(t, err, "Could not get signing root of beacon block header")
sig0 = privKeys[0].Sign(signingRoot[:])
sig1 = privKeys[1].Sign(signingRoot[:])
aggregateSig = bls.AggregateSignatures([]bls.Signature{sig0, sig1})
att2.Signature = aggregateSig.Marshal()
slashings := []*ethpb.AttesterSlashing{
{
Attestation_1: att1,
Attestation_2: att2,
},
}
currentSlot := 2 * params.BeaconConfig().SlotsPerEpoch
require.NoError(t, beaconState.SetSlot(currentSlot))
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: slashings,
},
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
require.NoError(t, err)
newRegistry := newState.Validators()
// Given the intersection of slashable indices is [1], only validator
// at index 1 should be slashed and exited. We confirm this below.
if newRegistry[1].ExitEpoch != beaconState.Validators()[1].ExitEpoch {
t.Errorf(
`
Expected validator at index 1's exit epoch to match
%d, received %d instead
`,
beaconState.Validators()[1].ExitEpoch,
newRegistry[1].ExitEpoch,
)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,12 @@ import (
fuzz "github.com/google/gofuzz"
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
ethereum_beacon_p2p_v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
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) {
@@ -25,7 +24,8 @@ func TestFuzzProcessAttestationNoVerify_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(att)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
_, err = ProcessAttestationNoVerify(ctx, s, att)
require.NoError(t, err)
_, err = ProcessAttestationNoVerifySignature(ctx, s, att)
_ = err
}
}
@@ -40,7 +40,8 @@ func TestFuzzProcessBlockHeader_10000(t *testing.T) {
fuzzer.Fuzz(block)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
_, err = ProcessBlockHeader(s, block)
require.NoError(t, err)
_, err = ProcessBlockHeader(context.Background(), s, block)
_ = err
}
}
@@ -63,6 +64,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 +72,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)
}
}
}
@@ -105,6 +107,7 @@ func TestFuzzEth1DataHasEnoughSupport_10000(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&ethereum_beacon_p2p_v1.BeaconState{
Eth1DataVotes: stateVotes,
})
require.NoError(t, err)
_, err = Eth1DataHasEnoughSupport(s, eth1data)
_ = err
}
@@ -120,6 +123,7 @@ func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeaderNoVerify(s, block)
_ = err
}
@@ -128,15 +132,16 @@ 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{}
b := &eth.SignedBeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessRandao(s, blockBody)
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)
}
}
}
@@ -150,6 +155,7 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := beaconstate.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)
@@ -160,15 +166,16 @@ 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{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessProposerSlashings(ctx, s, blockBody)
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)
}
}
}
@@ -181,6 +188,7 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(proposerSlashing)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyProposerSlashing(s, proposerSlashing)
_ = err
}
@@ -189,15 +197,16 @@ 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{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttesterSlashings(ctx, s, blockBody)
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)
}
}
}
@@ -211,6 +220,7 @@ func TestFuzzVerifyAttesterSlashing_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attesterSlashing)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttesterSlashing(ctx, s, attesterSlashing)
_ = err
}
@@ -241,15 +251,16 @@ 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{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttestations(ctx, s, blockBody)
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)
}
}
}
@@ -257,15 +268,16 @@ func TestFuzzProcessAttestations_10000(t *testing.T) {
func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessAttestationsNoVerify(ctx, s, blockBody)
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)
}
}
}
@@ -279,6 +291,7 @@ func TestFuzzProcessAttestation_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := beaconstate.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)
@@ -295,6 +308,7 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(idxAttestation)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyIndexedAttestation(ctx, s, idxAttestation)
_ = err
}
@@ -309,7 +323,8 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
err = VerifyAttestation(ctx, s, attestation)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
}
}
@@ -317,15 +332,16 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessDeposits(ctx, s, blockBody)
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)
}
}
}
@@ -340,7 +356,8 @@ func TestFuzzProcessPreGenesisDeposit_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessPreGenesisDeposit(ctx, s, deposit)
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)
}
@@ -356,7 +373,8 @@ func TestFuzzProcessDeposit_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessDeposit(s, deposit)
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)
}
@@ -371,6 +389,7 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = verifyDeposit(s, deposit)
_ = err
}
@@ -379,15 +398,16 @@ 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{}
b := &eth.SignedBeaconBlock{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessVoluntaryExits(ctx, s, blockBody)
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)
}
}
}
@@ -395,14 +415,15 @@ func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethereum_beacon_p2p_v1.BeaconState{}
blockBody := &eth.BeaconBlockBody{}
b := &eth.SignedBeaconBlock{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
fuzzer.Fuzz(b)
s, err := beaconstate.InitializeFromProtoUnsafe(state)
r, err := ProcessVoluntaryExitsNoVerify(s, blockBody)
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)
}
}
}
@@ -419,7 +440,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
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,8 @@ import (
"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"
)
func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
@@ -37,46 +39,44 @@ 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())
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
signingRoot, err := helpers.ComputeSigningRoot(att1.Data, domain)
if err != nil {
t.Errorf("Could not get signing root of beacon block header: %v", err)
}
require.NoError(t, err, "Could not get signing root of beacon block header")
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)
if err != nil {
t.Errorf("Could not get signing root of beacon block header: %v", err)
}
assert.NoError(t, err, "Could not get signing root of beacon block header")
aggSigs = []bls.Signature{}
for _, index := range setB {
sig := privKeys[index].Sign(signingRoot[:])
aggSigs = append(aggSigs, sig)
}
aggregateSig = bls.AggregateSignatures(aggSigs)
att2.Signature = aggregateSig.Marshal()[:]
att2.Signature = aggregateSig.Marshal()
slashings := []*ethpb.AttesterSlashing{
{
@@ -86,20 +86,17 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
}
currentSlot := 2 * params.BeaconConfig().SlotsPerEpoch
if err := beaconState.SetSlot(currentSlot); err != nil {
t.Fatal(err)
}
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)
if err != nil {
t.Fatal(err)
}
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
require.NoError(t, err)
newRegistry := newState.Validators()
if !newRegistry[expectedSlashedVal].Slashed {
t.Errorf("Validator with index %d was not slashed despite performing a double vote", expectedSlashedVal)

View File

@@ -1,21 +0,0 @@
package blocks_test
import (
"bytes"
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
)
func TestGenesisBlock_InitializedCorrectly(t *testing.T) {
stateHash := []byte{0}
b1 := blocks.NewGenesisBlock(stateHash)
if b1.Block.ParentRoot == nil {
t.Error("genesis block missing ParentHash field")
}
if !bytes.Equal(b1.Block.StateRoot, stateHash) {
t.Error("genesis block StateRootHash32 isn't initialized correctly")
}
}

View File

@@ -0,0 +1,272 @@
package blocks
import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
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/depositutil"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/trieutil"
)
// ProcessPreGenesisDeposits processes a deposit for the beacon state before chainstart.
func ProcessPreGenesisDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
deposits []*ethpb.Deposit,
) (*stateTrie.BeaconState, error) {
var err error
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")
}
for _, deposit := range deposits {
pubkey := deposit.Data.PublicKey
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubkey))
if !ok {
return beaconState, nil
}
balance, err := beaconState.BalanceAtIndex(index)
if err != nil {
return nil, err
}
validator, err := beaconState.ValidatorAtIndex(index)
if err != nil {
return nil, err
}
validator.EffectiveBalance = mathutil.Min(balance-balance%params.BeaconConfig().EffectiveBalanceIncrement, params.BeaconConfig().MaxEffectiveBalance)
if validator.EffectiveBalance ==
params.BeaconConfig().MaxEffectiveBalance {
validator.ActivationEligibilityEpoch = 0
validator.ActivationEpoch = 0
}
if err := beaconState.UpdateValidatorAtIndex(index, validator); err != nil {
return nil, err
}
}
return beaconState, nil
}
// ProcessDeposits is one of the operations performed on each processed
// beacon block to verify queued validators from the Ethereum 1.0 Deposit Contract
// into the beacon chain.
//
// Spec pseudocode definition:
// For each deposit in block.body.deposits:
// process_deposit(state, deposit)
func ProcessDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
deposits := b.Block.Body.Deposits
var err error
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return nil, err
}
// Attempt to verify all deposit signatures at once, if this fails then fall back to processing
// individual deposits with signature verification enabled.
var verifySignature bool
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
log.WithError(err).Debug("Failed to verify deposit data, verifying signatures individually")
verifySignature = true
}
for _, deposit := range deposits {
if deposit == nil || deposit.Data == nil {
return nil, errors.New("got a nil deposit in block")
}
beaconState, err = ProcessDeposit(beaconState, deposit, verifySignature)
if err != nil {
return nil, errors.Wrapf(err, "could not process deposit from %#x", bytesutil.Trunc(deposit.Data.PublicKey))
}
}
return beaconState, nil
}
// ProcessDeposit takes in a deposit object and inserts it
// into the registry as a new validator or balance change.
//
// Spec pseudocode definition:
// def process_deposit(state: BeaconState, deposit: Deposit) -> None:
// # Verify the Merkle branch
// assert is_valid_merkle_branch(
// leaf=hash_tree_root(deposit.data),
// branch=deposit.proof,
// depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1, # Add 1 for the List length mix-in
// index=state.eth1_deposit_index,
// root=state.eth1_data.deposit_root,
// )
//
// # Deposits must be processed in order
// state.eth1_deposit_index += 1
//
// pubkey = deposit.data.pubkey
// amount = deposit.data.amount
// validator_pubkeys = [v.pubkey for v in state.validators]
// if pubkey not in validator_pubkeys:
// # Verify the deposit signature (proof of possession) which is not checked by the deposit contract
// deposit_message = DepositMessage(
// pubkey=deposit.data.pubkey,
// withdrawal_credentials=deposit.data.withdrawal_credentials,
// amount=deposit.data.amount,
// )
// domain = compute_domain(DOMAIN_DEPOSIT) # Fork-agnostic domain since deposits are valid across forks
// signing_root = compute_signing_root(deposit_message, domain)
// if not bls.Verify(pubkey, signing_root, deposit.data.signature):
// return
//
// # Add validator and balance entries
// state.validators.append(get_validator_from_deposit(state, deposit))
// state.balances.append(amount)
// else:
// # Increase balance by deposit amount
// index = ValidatorIndex(validator_pubkeys.index(pubkey))
// increase_balance(state, index, amount)
func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (*stateTrie.BeaconState, error) {
if err := verifyDeposit(beaconState, deposit); err != nil {
if deposit == nil || deposit.Data == nil {
return nil, err
}
return nil, errors.Wrapf(err, "could not verify deposit from %#x", bytesutil.Trunc(deposit.Data.PublicKey))
}
if err := beaconState.SetEth1DepositIndex(beaconState.Eth1DepositIndex() + 1); err != nil {
return nil, err
}
pubKey := deposit.Data.PublicKey
amount := deposit.Data.Amount
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubKey))
if !ok {
if verifySignature {
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return nil, err
}
depositSig := deposit.Data.Signature
if err := verifyDepositDataSigningRoot(deposit.Data, pubKey, depositSig, 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
}
}
effectiveBalance := amount - (amount % params.BeaconConfig().EffectiveBalanceIncrement)
if params.BeaconConfig().MaxEffectiveBalance < effectiveBalance {
effectiveBalance = params.BeaconConfig().MaxEffectiveBalance
}
if err := beaconState.AppendValidator(&ethpb.Validator{
PublicKey: pubKey,
WithdrawalCredentials: deposit.Data.WithdrawalCredentials,
ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch,
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
EffectiveBalance: effectiveBalance,
}); err != nil {
return nil, err
}
if err := beaconState.AppendBalance(amount); err != nil {
return nil, err
}
} else if err := helpers.IncreaseBalance(beaconState, index, amount); err != nil {
return nil, err
}
return beaconState, nil
}
func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) error {
// Verify Merkle proof of deposit and deposit trie root.
if deposit == nil || deposit.Data == nil {
return errors.New("received nil deposit or nil deposit data")
}
eth1Data := beaconState.Eth1Data()
if eth1Data == nil {
return errors.New("received nil eth1data in the beacon state")
}
receiptRoot := eth1Data.DepositRoot
leaf, err := deposit.Data.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not tree hash deposit data")
}
if ok := trieutil.VerifyMerkleBranch(
receiptRoot,
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 {
return depositutil.VerifyDepositSignature(obj, domain)
}
func verifyDepositDataWithDomain(ctx context.Context, deps []*ethpb.Deposit, domain []byte) error {
if len(deps) == 0 {
return nil
}
pks := make([]bls.PublicKey, len(deps))
sigs := make([][]byte, len(deps))
msgs := make([][32]byte, len(deps))
for i, dep := range deps {
if ctx.Err() != nil {
return ctx.Err()
}
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
sigs[i] = dep.Data.Signature
root, err := ssz.SigningRoot(dep.Data)
if err != nil {
return errors.Wrap(err, "could not get signing root")
}
signingData := &pb.SigningData{
ObjectRoot: root[:],
Domain: domain,
}
ctrRoot, err := signingData.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get container root")
}
msgs[i] = ctrRoot
}
verify, err := bls.VerifyMultipleSignatures(sigs, msgs, pks)
if err != nil {
return errors.Errorf("could not verify multiple signatures: %v", err)
}
if !verify {
return errors.New("one or more deposit signatures did not verify")
}
return nil
}

View File

@@ -0,0 +1,273 @@
package blocks_test
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"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"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/shared/trieutil"
)
func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
// Same validator created 3 valid deposits within the same block
testutil.ResetCache()
dep, _, err := testutil.DeterministicDepositsAndKeysSameValidator(3)
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
require.NoError(t, err)
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]},
},
}
registry := []*ethpb.Validator{
{
PublicKey: []byte{1},
WithdrawalCredentials: []byte{1, 2, 3},
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
Fork: &pb.Fork{
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
},
})
require.NoError(t, err)
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")
}
func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
deposit := &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1, 2, 3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
}
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))
require.NoError(t, err, "Could not generate trie")
proof, err := depositTrie.MerkleProof(0)
require.NoError(t, err, "Could not generate proof")
deposit.Proof = proof
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{deposit},
},
}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{0},
BlockHash: []byte{1},
},
})
require.NoError(t, err)
want := "deposit root did not verify"
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
dep, _, err := testutil.DeterministicDepositsAndKeys(1)
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{dep[0]},
},
}
registry := []*ethpb.Validator{
{
PublicKey: []byte{1},
WithdrawalCredentials: []byte{1, 2, 3},
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
Fork: &pb.Fork{
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
},
})
require.NoError(t, err)
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(
"Expected state validator balances index 0 to equal %d, received %d",
dep[0].Data.Amount,
newState.Balances()[1],
)
}
}
func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T) {
sk := bls.RandKey()
deposit := &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: sk.PublicKey().Marshal(),
Amount: 1000,
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
}
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 := 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))
require.NoError(t, err, "Could not generate trie")
proof, err := depositTrie.MerkleProof(0)
require.NoError(t, err, "Could not generate proof")
deposit.Proof = proof
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Deposits: []*ethpb.Deposit{deposit},
},
}
registry := []*ethpb.Validator{
{
PublicKey: []byte{1, 2, 3},
},
{
PublicKey: sk.PublicKey().Marshal(),
WithdrawalCredentials: []byte{1},
},
}
balances := []uint64{0, 50}
root := depositTrie.Root()
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: &ethpb.Eth1Data{
DepositRoot: root[:],
BlockHash: root[:],
},
})
require.NoError(t, err)
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")
}
func TestProcessDeposit_AddsNewValidatorDeposit(t *testing.T) {
//Similar to TestProcessDeposits_AddsNewValidatorDeposit except that this test directly calls ProcessDeposit
dep, _, err := testutil.DeterministicDepositsAndKeys(1)
require.NoError(t, err)
eth1Data, err := testutil.DeterministicEth1Data(len(dep))
require.NoError(t, err)
registry := []*ethpb.Validator{
{
PublicKey: []byte{1},
WithdrawalCredentials: []byte{1, 2, 3},
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
Fork: &pb.Fork{
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposit(beaconState, dep[0], true)
require.NoError(t, err, "Process deposit failed")
assert.Equal(t, 2, len(newState.Validators()), "Expected validator list to have length 2")
assert.Equal(t, 2, len(newState.Balances()), "Expected validator balances list to have length 2")
if newState.Balances()[1] != dep[0].Data.Amount {
t.Errorf(
"Expected state validator balances index 1 to equal %d, received %d",
dep[0].Data.Amount,
newState.Balances()[1],
)
}
}
func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
// Same test settings as in TestProcessDeposit_AddsNewValidatorDeposit, except that we use an invalid signature
dep, _, err := testutil.DeterministicDepositsAndKeys(1)
require.NoError(t, err)
dep[0].Data.Signature = make([]byte, 96)
trie, _, err := testutil.DepositTrieFromDeposits(dep)
require.NoError(t, err)
root := trie.Root()
eth1Data := &ethpb.Eth1Data{
DepositRoot: root[:],
DepositCount: 1,
}
registry := []*ethpb.Validator{
{
PublicKey: []byte{1},
WithdrawalCredentials: []byte{1, 2, 3},
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
Fork: &pb.Fork{
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposit(beaconState, dep[0], true)
require.NoError(t, err, "Expected invalid block deposit to be ignored without error")
if newState.Eth1DepositIndex() != 1 {
t.Errorf(
"Expected Eth1DepositIndex to be increased by 1 after processing an invalid deposit, received change: %v",
newState.Eth1DepositIndex(),
)
}
if len(newState.Validators()) != 1 {
t.Errorf("Expected validator list to have length 1, received: %v", len(newState.Validators()))
}
if len(newState.Balances()) != 1 {
t.Errorf("Expected validator balances list to have length 1, received: %v", len(newState.Balances()))
}
if newState.Balances()[0] != 0 {
t.Errorf("Expected validator balance at index 0 to stay 0, received: %v", newState.Balances()[0])
}
}

View File

@@ -0,0 +1,76 @@
package blocks
import (
"bytes"
"context"
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessEth1DataInBlock is an operation performed on each
// beacon block to ensure the ETH1 data votes are processed
// into the beacon state.
//
// Official spec definition:
// def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
// state.eth1_data_votes.append(body.eth1_data)
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
// state.latest_eth1_data = body.eth1_data
func ProcessEth1DataInBlock(ctx context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) (*stateTrie.BeaconState, error) {
block := b.Block
if beaconState == nil {
return nil, errors.New("nil state")
}
if block == nil || block.Body == nil {
return nil, errors.New("nil block or block withought body")
}
if err := beaconState.AppendEth1DataVotes(block.Body.Eth1Data); err != nil {
return nil, err
}
hasSupport, err := Eth1DataHasEnoughSupport(beaconState, block.Body.Eth1Data)
if err != nil {
return nil, err
}
if hasSupport {
if err := beaconState.SetEth1Data(block.Body.Eth1Data); err != nil {
return nil, err
}
}
return beaconState, nil
}
// AreEth1DataEqual checks equality between two eth1 data objects.
func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
if a == nil && b == nil {
return true
}
if a == nil || b == nil {
return false
}
return a.DepositCount == b.DepositCount &&
bytes.Equal(a.BlockHash, b.BlockHash) &&
bytes.Equal(a.DepositRoot, b.DepositRoot)
}
// Eth1DataHasEnoughSupport returns true when the given eth1data has more than 50% votes in the
// eth1 voting period. A vote is cast by including eth1data in a block and part of state processing
// appends eth1data to the state in the Eth1DataVotes list. Iterating through this list checks the
// votes to see if they match the eth1data.
func Eth1DataHasEnoughSupport(beaconState *stateTrie.BeaconState, data *ethpb.Eth1Data) (bool, error) {
voteCount := uint64(0)
data = stateTrie.CopyETH1Data(data)
for _, vote := range beaconState.Eth1DataVotes() {
if AreEth1DataEqual(vote, data) {
voteCount++
}
}
// If 50+% majority converged on the same eth1data, then it has enough support to update the
// state.
support := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
return voteCount*2 > support, nil
}

View File

@@ -1,14 +1,20 @@
package blocks_test
import (
"context"
"fmt"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"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"
)
func FakeDeposits(n uint64) []*ethpb.Eth1Data {
@@ -16,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
@@ -33,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,
@@ -41,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,
@@ -49,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,
@@ -66,13 +72,9 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: tt.stateVotes,
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
result, err := blocks.Eth1DataHasEnoughSupport(s, tt.data)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
if result != tt.hasSupport {
t.Errorf(
@@ -85,3 +87,108 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
})
}
}
func TestAreEth1DataEqual(t *testing.T) {
type args struct {
a *ethpb.Eth1Data
b *ethpb.Eth1Data
}
tests := []struct {
name string
args args
want bool
}{
{
name: "true when both are nil",
args: args{
a: nil,
b: nil,
},
want: true,
},
{
name: "false when only one is nil",
args: args{
a: nil,
b: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
DepositCount: 0,
BlockHash: make([]byte, 32),
},
},
want: false,
},
{
name: "true when real equality",
args: args{
a: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
DepositCount: 0,
BlockHash: make([]byte, 32),
},
b: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
DepositCount: 0,
BlockHash: make([]byte, 32),
},
},
want: true,
},
{
name: "false is field value differs",
args: args{
a: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
DepositCount: 0,
BlockHash: make([]byte, 32),
},
b: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
DepositCount: 64,
BlockHash: make([]byte, 32),
},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, blocks.AreEth1DataEqual(tt.args.a, tt.args.b))
})
}
}
func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
beaconState, err := beaconstate.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: []*ethpb.Eth1Data{},
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{2},
BlockHash: []byte{3},
},
},
}
period := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
for i := uint64(0); i < period; i++ {
beaconState, err = blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
require.NoError(t, err)
}
newETH1DataVotes := beaconState.Eth1DataVotes()
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), beaconstate.CopyETH1Data(b.Block.Body.Eth1Data)) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
b.Block.Body.Eth1Data,
beaconState.Eth1Data(),
)
}
}

View File

@@ -0,0 +1,182 @@
package blocks
import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessVoluntaryExits is one of the operations performed
// on each processed beacon block to determine which validators
// should exit the state's validator registry.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
// # Initiate exit
// initiate_validator_exit(state, exit.validator_index)
func ProcessVoluntaryExits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
exits := body.VoluntaryExits
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
return nil, errors.New("nil voluntary exit in block body")
}
val, err := beaconState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)
if err != nil {
return nil, err
}
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)
if err != nil {
return nil, err
}
}
return beaconState, nil
}
// ProcessVoluntaryExitsNoVerifySignature processes all the voluntary exits in
// a block body, without verifying their BLS signatures.
// This function is here to satisfy fuzz tests.
func ProcessVoluntaryExitsNoVerifySignature(
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
exits := body.VoluntaryExits
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
return nil, errors.New("nil exit")
}
val, err := beaconState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)
if err != nil {
return nil, err
}
if err := verifyExitConditions(val, beaconState.Slot(), exit.Exit); err != nil {
return nil, err
}
// Validate that fork and genesis root are valid.
_, err = helpers.Domain(beaconState.Fork(), exit.Exit.Epoch, params.BeaconConfig().DomainVoluntaryExit, beaconState.GenesisValidatorRoot())
if err != nil {
return nil, err
}
beaconState, err = v.InitiateValidatorExit(beaconState, exit.Exit.ValidatorIndex)
if err != nil {
return nil, errors.Wrapf(err, "failed to process voluntary exit at index %d", idx)
}
}
return beaconState, nil
}
// VerifyExitAndSignature implements the spec defined validation for voluntary exits.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
func VerifyExitAndSignature(validator *stateTrie.ReadOnlyValidator, currentSlot uint64, fork *pb.Fork, signed *ethpb.SignedVoluntaryExit, genesisRoot []byte) error {
if signed == nil || signed.Exit == nil {
return errors.New("nil exit")
}
exit := signed.Exit
if err := verifyExitConditions(validator, currentSlot, exit); err != nil {
return err
}
domain, err := helpers.Domain(fork, exit.Epoch, params.BeaconConfig().DomainVoluntaryExit, genesisRoot)
if err != nil {
return err
}
valPubKey := validator.PublicKey()
if err := helpers.VerifySigningRoot(exit, valPubKey[:], signed.Signature, domain); err != nil {
return helpers.ErrSigFailedToVerify
}
return nil
}
// verifyExitConditions implements the spec defined validation for voluntary exits(excluding signatures).
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
func verifyExitConditions(validator *stateTrie.ReadOnlyValidator, currentSlot uint64, exit *ethpb.VoluntaryExit) error {
currentEpoch := helpers.SlotToEpoch(currentSlot)
// Verify the validator is active.
if !helpers.IsActiveValidatorUsingTrie(validator, currentEpoch) {
return errors.New("non-active validator cannot exit")
}
// Verify the validator has not yet submitted an exit.
if validator.ExitEpoch() != params.BeaconConfig().FarFutureEpoch {
return fmt.Errorf(
"validator has already submitted an exit, which will take place at epoch: %v",
validator.ExitEpoch())
}
// Exits must specify an epoch when they become valid; they are not valid before then.
if currentEpoch < exit.Epoch {
return fmt.Errorf("expected current epoch >= exit epoch, received %d < %d", currentEpoch, exit.Epoch)
}
// 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: %d epochs vs required %d epochs",
currentEpoch,
validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod,
)
}
return nil
}

View File

@@ -0,0 +1,206 @@
package blocks_test
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"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/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessVoluntaryExits_ValidatorNotActive(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 0,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "non-active validator cannot exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_InvalidExitEpoch(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 10,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 0,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "expected current epoch >= exit epoch"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 0,
Epoch: 0,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 10,
})
require.NoError(t, err)
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, 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)
}
func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 0,
Epoch: 0,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
ActivationEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Fork: &pb.Fork{
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
},
Slot: params.BeaconConfig().SlotsPerEpoch * 5,
})
require.NoError(t, err)
err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, err)
priv := bls.RandKey()
val, err := state.ValidatorAtIndex(0)
require.NoError(t, err)
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)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
stateCopy := state.Copy()
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) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
}
// Check conformance with NoVerify Exit Method.
newState, err = blocks.ProcessVoluntaryExitsNoVerifySignature(stateCopy, b.Block.Body)
require.NoError(t, err, "Could not process exits")
newRegistry = newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
}
}

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

@@ -0,0 +1,17 @@
package blocks_test
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 := bytesutil.PadTo([]byte{0}, 32)
b1 := blocks.NewGenesisBlock(stateHash)
assert.NotNil(t, b1.Block.ParentRoot, "Genesis block missing ParentHash field")
assert.DeepEqual(t, b1.Block.StateRoot, stateHash, "Genesis block StateRootHash32 isn't initialized correctly")
}

View File

@@ -0,0 +1,136 @@
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/shared/params"
)
// ProcessBlockHeader validates a block by its header.
//
// Spec pseudocode definition:
//
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
// # Verify that the slots match
// assert block.slot == state.slot
// # Verify that proposer index is the correct index
// assert block.proposer_index == get_beacon_proposer_index(state)
// # Verify that the parent matches
// assert block.parent_root == hash_tree_root(state.latest_block_header)
// # Save current block as the new latest block
// state.latest_block_header = BeaconBlockHeader(
// slot=block.slot,
// parent_root=block.parent_root,
// # state_root: zeroed, overwritten in the next `process_slot` call
// body_root=hash_tree_root(block.body),
// # signature is always zeroed
// )
// # Verify proposer is not slashed
// proposer = state.validators[get_beacon_proposer_index(state)]
// assert not proposer.slashed
// # Verify proposer signature
// assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
func ProcessBlockHeader(
ctx context.Context,
beaconState *stateTrie.BeaconState,
block *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
beaconState, err := ProcessBlockHeaderNoVerify(beaconState, block.Block)
if err != nil {
return nil, err
}
// Verify proposer signature.
if err := VerifyBlockSignature(beaconState, block); err != nil {
return nil, err
}
return beaconState, nil
}
// ProcessBlockHeaderNoVerify validates a block by its header but skips proposer
// signature verification.
//
// WARNING: This method does not verify proposer signature. This is used for proposer to compute state root
// using a unsigned block.
//
// Spec pseudocode definition:
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
// # Verify that the slots match
// assert block.slot == state.slot
// # Verify that proposer index is the correct index
// assert block.proposer_index == get_beacon_proposer_index(state)
// # Verify that the parent matches
// assert block.parent_root == hash_tree_root(state.latest_block_header)
// # Save current block as the new latest block
// state.latest_block_header = BeaconBlockHeader(
// slot=block.slot,
// parent_root=block.parent_root,
// # state_root: zeroed, overwritten in the next `process_slot` call
// body_root=hash_tree_root(block.body),
// # signature is always zeroed
// )
// # Verify proposer is not slashed
// proposer = state.validators[get_beacon_proposer_index(state)]
// assert not proposer.slashed
func ProcessBlockHeaderNoVerify(
beaconState *stateTrie.BeaconState,
block *ethpb.BeaconBlock,
) (*stateTrie.BeaconState, error) {
if block == nil {
return nil, errors.New("nil block")
}
if beaconState.Slot() != block.Slot {
return nil, fmt.Errorf("state slot: %d is different than block slot: %d", beaconState.Slot(), block.Slot)
}
idx, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, err
}
if block.ProposerIndex != idx {
return nil, fmt.Errorf("proposer index: %d is different than calculated: %d", block.ProposerIndex, idx)
}
parentHeader := beaconState.LatestBlockHeader()
if parentHeader.Slot >= block.Slot {
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", block.Slot, parentHeader.Slot)
}
parentRoot, err := parentHeader.HashTreeRoot()
if err != nil {
return nil, err
}
if !bytes.Equal(block.ParentRoot, parentRoot[:]) {
return nil, fmt.Errorf(
"parent root %#x does not match the latest block header signing root in state %#x",
block.ParentRoot, parentRoot)
}
proposer, err := beaconState.ValidatorAtIndexReadOnly(idx)
if err != nil {
return nil, err
}
if proposer.Slashed() {
return nil, fmt.Errorf("proposer at index %d was previously slashed", idx)
}
bodyRoot, err := block.Body.HashTreeRoot()
if err != nil {
return nil, err
}
if err := beaconState.SetLatestBlockHeader(&ethpb.BeaconBlockHeader{
Slot: block.Slot,
ProposerIndex: block.ProposerIndex,
ParentRoot: block.ParentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
BodyRoot: bodyRoot[:],
}); err != nil {
return nil, err
}
return beaconState, nil
}

View File

@@ -0,0 +1,332 @@
package blocks_test
import (
"context"
"io/ioutil"
"testing"
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/sirupsen/logrus"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"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"
)
func init() {
logrus.SetOutput(ioutil.Discard) // Ignore "validator activated" logs
}
func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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 := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
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)
proposerIdx, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
validators[proposerIdx].Slashed = false
validators[proposerIdx].PublicKey = priv.PublicKey().Marshal()
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
_, 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,
ParentRoot: make([]byte, 32),
StateRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
}))
require.NoError(t, beaconState.SetSlot(10))
lbhdr, err := beaconState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
require.NoError(t, err)
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(context.Background(), beaconState, block)
want := "signature did not verify"
assert.ErrorContains(t, want, err)
}
func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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 := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv)
require.NoError(t, err)
validators[5896].PublicKey = priv.PublicKey().Marshal()
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 1,
Body: &ethpb.BeaconBlockBody{
RandaoReveal: []byte{'A', 'B', 'C'},
},
ParentRoot: lbhsr[:],
},
Signature: blockSig,
}
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
want := "is different than block slot"
assert.ErrorContains(t, want, err)
}
func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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()
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 := 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(context.Background(), state, block)
want := "does not match"
assert.ErrorContains(t, want, err)
}
func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 48),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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()
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 := 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(context.Background(), state, block)
want := "was previously slashed"
assert.ErrorContains(t, want, err)
}
func TestProcessBlockHeader_OK(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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 := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
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 := block.Block.Body.HashTreeRoot()
require.NoError(t, err, "Failed to hash block bytes got")
proposerIdx, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
validators[proposerIdx].Slashed = false
validators[proposerIdx].PublicKey = priv.PublicKey().Marshal()
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
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()
expected := &ethpb.BeaconBlockHeader{
ProposerIndex: pID,
Slot: block.Block.Slot,
ParentRoot: latestBlockSignedRoot[:],
BodyRoot: bodyRoot[:],
StateRoot: zeroHash[:],
}
assert.Equal(t, true, proto.Equal(nsh, expected), "Expected %v, received %v", expected, nsh)
}
func TestBlockSignatureSet_OK(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: make([]byte, 32),
WithdrawalCredentials: make([]byte, 32),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
Slashed: true,
}
}
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 := state.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
priv := bls.RandKey()
pID, err := helpers.BeaconProposerIndex(state)
require.NoError(t, err)
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)
require.NoError(t, err)
validators[proposerIdx].Slashed = false
validators[proposerIdx].PublicKey = priv.PublicKey().Marshal()
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
set, err := blocks.BlockSignatureSet(state, block)
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Block signature set returned a set which was unable to be verified")
}

View File

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

View File

@@ -0,0 +1,101 @@
package blocks
import (
"context"
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessProposerSlashings is one of the operations performed
// on each processed beacon block to slash proposers based on
// slashing conditions if any slashable events occurred.
//
// Spec pseudocode definition:
// def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSlashing) -> None:
// """
// Process ``ProposerSlashing`` operation.
// """
// proposer = state.validator_registry[proposer_slashing.proposer_index]
// # Verify slots match
// assert proposer_slashing.header_1.slot == proposer_slashing.header_2.slot
// # But the headers are different
// assert proposer_slashing.header_1 != proposer_slashing.header_2
// # Check proposer is slashable
// assert is_slashable_validator(proposer, get_current_epoch(state))
// # Signatures are valid
// for header in (proposer_slashing.header_1, proposer_slashing.header_2):
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
// assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)
//
// slash_validator(state, proposer_slashing.proposer_index)
func ProcessProposerSlashings(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
var err error
for idx, slashing := range body.ProposerSlashings {
if slashing == nil {
return nil, errors.New("nil proposer slashings in block body")
}
if err = VerifyProposerSlashing(beaconState, slashing); err != nil {
return nil, errors.Wrapf(err, "could not verify proposer slashing %d", idx)
}
beaconState, err = v.SlashValidator(
beaconState, slashing.Header_1.Header.ProposerIndex,
)
if err != nil {
return nil, errors.Wrapf(err, "could not slash proposer index %d", slashing.Header_1.Header.ProposerIndex)
}
}
return beaconState, nil
}
// VerifyProposerSlashing verifies that the data provided from slashing is valid.
func VerifyProposerSlashing(
beaconState *stateTrie.BeaconState,
slashing *ethpb.ProposerSlashing,
) error {
if slashing.Header_1 == nil || slashing.Header_1.Header == nil || slashing.Header_2 == nil || slashing.Header_2.Header == nil {
return errors.New("nil header cannot be verified")
}
hSlot := slashing.Header_1.Header.Slot
if hSlot != slashing.Header_2.Header.Slot {
return fmt.Errorf("mismatched header slots, received %d == %d", slashing.Header_1.Header.Slot, slashing.Header_2.Header.Slot)
}
pIdx := slashing.Header_1.Header.ProposerIndex
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.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(hSlot)) {
return fmt.Errorf("validator with key %#x is not slashable", proposer.PublicKey())
}
headers := []*ethpb.SignedBeaconBlockHeader{slashing.Header_1, slashing.Header_2}
for _, header := range headers {
if err := helpers.ComputeDomainVerifySigningRoot(beaconState, pIdx, helpers.SlotToEpoch(hSlot),
header.Header, params.BeaconConfig().DomainBeaconProposer, header.Signature); err != nil {
return errors.Wrap(err, "could not verify beacon block header")
}
}
return nil
}

View File

@@ -0,0 +1,308 @@
package blocks_test
import (
"context"
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"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"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessProposerSlashings_UnmatchedHeaderSlots(t *testing.T) {
testutil.ResetCache()
beaconState, _ := testutil.DeterministicGenesisState(t, 20)
currentSlot := uint64(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: params.BeaconConfig().SlotsPerEpoch + 1,
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 0,
},
},
},
}
require.NoError(t, beaconState.SetSlot(currentSlot))
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
want := "mismatched header slots"
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessProposerSlashings_SameHeaders(t *testing.T) {
testutil.ResetCache()
beaconState, _ := testutil.DeterministicGenesisState(t, 2)
currentSlot := uint64(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 0,
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 1,
Slot: 0,
},
},
},
}
require.NoError(t, beaconState.SetSlot(currentSlot))
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
want := "expected slashing headers to differ"
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
registry := []*ethpb.Validator{
{
PublicKey: []byte("key"),
Slashed: true,
ActivationEpoch: 0,
WithdrawableEpoch: 0,
},
}
currentSlot := uint64(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 0,
Slot: 0,
BodyRoot: []byte("foo"),
},
Signature: bytesutil.PadTo([]byte("A"), 96),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 0,
Slot: 0,
BodyRoot: []byte("bar"),
},
Signature: bytesutil.PadTo([]byte("B"), 96),
},
},
}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: slashings,
},
}
want := fmt.Sprintf(
"validator with key %#x is not slashable",
bytesutil.ToBytes48(beaconState.Validators()[0].PublicKey),
)
_, err = blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
// We test the case when data is correct and verify the validator
// registry has been updated.
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
proposerIdx := uint64(1)
header1 := &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: proposerIdx,
Slot: 0,
ParentRoot: make([]byte, 32),
BodyRoot: make([]byte, 32),
StateRoot: bytesutil.PadTo([]byte("A"), 32),
},
}
var err error
header1.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, header1.Header, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
require.NoError(t, err)
header2 := &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: proposerIdx,
Slot: 0,
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])
require.NoError(t, err)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: header1,
Header_2: header2,
},
}
block := testutil.NewBeaconBlock()
block.Block.Body.ProposerSlashings = slashings
newState, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block)
require.NoError(t, err)
newStateVals := newState.Validators()
if newStateVals[1].ExitEpoch != beaconState.Validators()[1].ExitEpoch {
t.Errorf("Proposer with index 1 did not correctly exit,"+"wanted slot:%d, got:%d",
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))
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: bls.RandKey().Sign([]byte("foo")).Marshal(),
},
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: bls.RandKey().Sign([]byte("bar")).Marshal(),
},
},
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

@@ -0,0 +1,85 @@
package blocks
import (
"context"
"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/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessRandao checks the block proposer's
// randao commitment and generates a new randao mix to update
// in the beacon state's latest randao mixes slice.
//
// Spec pseudocode definition:
// def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
// epoch = get_current_epoch(state)
// # Verify RANDAO reveal
// proposer = state.validators[get_beacon_proposer_index(state)]
// signing_root = compute_signing_root(epoch, get_domain(state, DOMAIN_RANDAO))
// assert bls.Verify(proposer.pubkey, signing_root, body.randao_reveal)
// # Mix in RANDAO reveal
// mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal))
// state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
func ProcessRandao(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
body := b.Block.Body
buf, proposerPub, domain, err := randaoSigningData(beaconState)
if err != nil {
return nil, err
}
if err := verifySignature(buf, proposerPub, body.RandaoReveal, domain); err != nil {
return nil, errors.Wrap(err, "could not verify block randao")
}
beaconState, err = ProcessRandaoNoVerify(beaconState, body)
if err != nil {
return nil, errors.Wrap(err, "could not process randao")
}
return beaconState, nil
}
// ProcessRandaoNoVerify generates a new randao mix to update
// in the beacon state's latest randao mixes slice.
//
// Spec pseudocode definition:
// # Mix it in
// state.latest_randao_mixes[get_current_epoch(state) % LATEST_RANDAO_MIXES_LENGTH] = (
// xor(get_randao_mix(state, get_current_epoch(state)),
// hash(body.randao_reveal))
// )
func ProcessRandaoNoVerify(
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
// If block randao passed verification, we XOR the state's latest randao mix with the block's
// randao and update the state's corresponding latest randao mix value.
latestMixesLength := params.BeaconConfig().EpochsPerHistoricalVector
latestMixSlice, err := beaconState.RandaoMixAtIndex(currentEpoch % latestMixesLength)
if err != nil {
return nil, err
}
blockRandaoReveal := hashutil.Hash(body.RandaoReveal)
if len(blockRandaoReveal) != len(latestMixSlice) {
return nil, errors.New("blockRandaoReveal length doesnt match latestMixSlice length")
}
for i, x := range blockRandaoReveal {
latestMixSlice[i] ^= x
}
if err := beaconState.UpdateRandaoMixesAtIndex(currentEpoch%latestMixesLength, latestMixSlice); err != nil {
return nil, err
}
return beaconState, nil
}

View File

@@ -0,0 +1,94 @@
package blocks_test
import (
"bytes"
"context"
"encoding/binary"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"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"
"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"
)
func TestProcessRandao_IncorrectProposerFailsVerification(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
// We fetch the proposer's index as that is whom the RANDAO will be verified against.
proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
require.NoError(t, err)
epoch := uint64(0)
buf := make([]byte, 32)
binary.LittleEndian.PutUint64(buf, epoch)
domain, err := helpers.Domain(beaconState.Fork(), epoch, params.BeaconConfig().DomainRandao, beaconState.GenesisValidatorRoot())
require.NoError(t, err)
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[:])
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
RandaoReveal: epochSignature.Marshal(),
},
}
want := "block randao: signature did not verify"
_, err = blocks.ProcessRandao(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
func TestProcessRandao_SignatureVerifiesAndUpdatesLatestStateMixes(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
epoch := helpers.CurrentEpoch(beaconState)
epochSignature, err := testutil.RandaoReveal(beaconState, epoch, privKeys)
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
RandaoReveal: epochSignature,
},
}
newState, err := blocks.ProcessRandao(
context.Background(),
beaconState,
b,
)
require.NoError(t, err, "Unexpected error processing block randao")
currentEpoch := helpers.CurrentEpoch(beaconState)
mix := newState.RandaoMixes()[currentEpoch%params.BeaconConfig().EpochsPerHistoricalVector]
if bytes.Equal(mix, params.BeaconConfig().ZeroHash[:]) {
t.Errorf(
"Expected empty signature to be overwritten by randao reveal, received %v",
params.BeaconConfig().EmptySignature,
)
}
}
func TestRandaoSignatureSet_OK(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
epoch := helpers.CurrentEpoch(beaconState)
epochSignature, err := testutil.RandaoReveal(beaconState, epoch, privKeys)
require.NoError(t, err)
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
RandaoReveal: epochSignature,
},
}
set, _, err := blocks.RandaoSignatureSet(beaconState, block.Body)
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Unable to verify randao signature set")
}

View File

@@ -0,0 +1,221 @@
package blocks
import (
"context"
"encoding/binary"
"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"
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/params"
)
// 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) {
publicKey, err := bls.PublicKeyFromBytes(pub)
if err != nil {
return nil, errors.Wrap(err, "could not convert bytes to public key")
}
signingData := &pb.SigningData{
ObjectRoot: signedData,
Domain: domain,
}
root, err := signingData.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash container")
}
return &bls.SignatureSet{
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 {
set, err := retrieveSignatureSet(signedData, pub, signature, domain)
if err != nil {
return err
}
if len(set.Signatures) != 1 {
return errors.Errorf("signature set contains %d signatures instead of 1", len(set.Signatures))
}
// We assume only one signature set is returned here.
sig := set.Signatures[0]
publicKey := set.PublicKeys[0]
root := set.Messages[0]
rSig, err := bls.SignatureFromBytes(sig)
if err != nil {
return err
}
if !rSig.Verify(publicKey, root[:]) {
return helpers.ErrSigFailedToVerify
}
return nil
}
// VerifyBlockSignature verifies the proposer signature of a beacon block.
func VerifyBlockSignature(beaconState *stateTrie.BeaconState, block *ethpb.SignedBeaconBlock) error {
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconProposer, beaconState.GenesisValidatorRoot())
if err != nil {
return err
}
proposer, err := beaconState.ValidatorAtIndex(block.Block.ProposerIndex)
if err != nil {
return err
}
proposerPubKey := proposer.PublicKey
return helpers.VerifyBlockSigningRoot(block.Block, proposerPubKey, block.Signature, domain)
}
// BlockSignatureSet retrieves the block signature set from the provided block and its corresponding state.
func BlockSignatureSet(beaconState *stateTrie.BeaconState, block *ethpb.SignedBeaconBlock) (*bls.SignatureSet, error) {
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconProposer, beaconState.GenesisValidatorRoot())
if err != nil {
return nil, err
}
proposer, err := beaconState.ValidatorAtIndex(block.Block.ProposerIndex)
if err != nil {
return nil, err
}
proposerPubKey := proposer.PublicKey
return helpers.RetrieveBlockSignatureSet(block.Block, proposerPubKey, block.Signature, domain)
}
// RandaoSignatureSet retrieves the relevant randao specific signature set object
// from a block and its corresponding state.
func RandaoSignatureSet(beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*bls.SignatureSet, *stateTrie.BeaconState, error) {
buf, proposerPub, domain, err := randaoSigningData(beaconState)
if err != nil {
return nil, nil, err
}
set, err := retrieveSignatureSet(buf, proposerPub, body.RandaoReveal, domain)
if err != nil {
return nil, nil, err
}
return set, beaconState, nil
}
// retrieves the randao related signing data from the state.
func randaoSigningData(beaconState *stateTrie.BeaconState) ([]byte, []byte, []byte, error) {
proposerIdx, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "could not get beacon proposer index")
}
proposerPub := beaconState.PubkeyAtIndex(proposerIdx)
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
buf := make([]byte, 32)
binary.LittleEndian.PutUint64(buf, currentEpoch)
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainRandao, beaconState.GenesisValidatorRoot())
if err != nil {
return nil, nil, nil, err
}
return buf, proposerPub[:], domain, nil
}
// Method to break down attestations of the same domain and collect them into a single signature set.
func createAttestationSignatureSet(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) (*bls.SignatureSet, error) {
if len(atts) == 0 {
return nil, nil
}
sigs := make([][]byte, len(atts))
pks := make([]bls.PublicKey, len(atts))
msgs := make([][32]byte, len(atts))
for i, a := range atts {
sigs[i] = a.Signature
c, err := helpers.BeaconCommitteeFromState(beaconState, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return nil, err
}
ia := attestationutil.ConvertToIndexed(ctx, a, c)
if err := attestationutil.IsValidAttestationIndices(ctx, ia); err != nil {
return nil, err
}
indices := ia.AttestingIndices
pubkeys := make([][]byte, len(indices))
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
pubkeys[i] = pubkeyAtIdx[:]
}
aggP, err := bls.AggregatePublicKeys(pubkeys)
if err != nil {
return nil, err
}
pks[i] = aggP
root, err := helpers.ComputeSigningRoot(ia.Data, domain)
if err != nil {
return nil, errors.Wrap(err, "could not get signing root of object")
}
msgs[i] = root
}
return &bls.SignatureSet{
Signatures: sigs,
PublicKeys: pks,
Messages: msgs,
}, nil
}
// AttestationSignatureSet retrieves all the related attestation signature data such as the relevant public keys,
// signatures and attestation signing data and collate it into a signature set object.
func AttestationSignatureSet(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation) (*bls.SignatureSet, error) {
if len(atts) == 0 {
return bls.NewSet(), nil
}
fork := beaconState.Fork()
gvr := beaconState.GenesisValidatorRoot()
dt := params.BeaconConfig().DomainBeaconAttester
// Split attestations by fork. Note: the signature domain will differ based on the fork.
var preForkAtts []*ethpb.Attestation
var postForkAtts []*ethpb.Attestation
for _, a := range atts {
if helpers.SlotToEpoch(a.Data.Slot) < fork.Epoch {
preForkAtts = append(preForkAtts, a)
} else {
postForkAtts = append(postForkAtts, a)
}
}
set := bls.NewSet()
// Check attestations from before the fork.
if fork.Epoch > 0 { // Check to prevent underflow.
prevDomain, err := helpers.Domain(fork, fork.Epoch-1, dt, gvr)
if err != nil {
return nil, err
}
aSet, err := createAttestationSignatureSet(ctx, beaconState, preForkAtts, prevDomain)
if err != nil {
return nil, err
}
set.Join(aSet)
} else if len(preForkAtts) > 0 {
// This is a sanity check that preForkAtts were not ignored when fork.Epoch == 0. This
// condition is not possible, but it doesn't hurt to check anyway.
return nil, errors.New("some attestations were not verified from previous fork before genesis")
}
// Then check attestations from after the fork.
currDomain, err := helpers.Domain(fork, fork.Epoch, dt, gvr)
if err != nil {
return nil, err
}
aSet, err := createAttestationSignatureSet(ctx, beaconState, postForkAtts, currDomain)
if err != nil {
return nil, err
}
return set.Join(aSet), nil
}

View File

@@ -38,8 +38,10 @@ go_test(
"//beacon-chain/core/state/stateutils:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/require: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",
@@ -72,8 +74,10 @@ go_test(
"//beacon-chain/core/state/stateutils:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/require: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",

View File

@@ -8,25 +8,20 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func runAttestationTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attestation/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
folderPath := path.Join(testsFolderPath, folder.Name())
attestationFile, err := testutil.BazelFileBytes(folderPath, "attestation.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
att := &ethpb.Attestation{}
if err := att.UnmarshalSSZ(attestationFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, att.UnmarshalSSZ(attestationFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{att}}
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttestations)

View File

@@ -8,25 +8,20 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func runAttesterSlashingTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attester_slashing/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
folderPath := path.Join(testsFolderPath, folder.Name())
attSlashingFile, err := testutil.BazelFileBytes(folderPath, "attester_slashing.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
attSlashing := &ethpb.AttesterSlashing{}
if err := attSlashing.UnmarshalSSZ(attSlashingFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, attSlashing.UnmarshalSSZ(attSlashingFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{AttesterSlashings: []*ethpb.AttesterSlashing{attSlashing}}
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttesterSlashings)

View File

@@ -14,64 +14,47 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"gopkg.in/d4l3k/messagediff.v1"
)
func runBlockHeaderTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/block_header/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "block.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
block := &ethpb.BeaconBlock{}
if err := block.UnmarshalSSZ(blockFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, block.UnmarshalSSZ(blockFile), "Failed to unmarshal")
preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
preBeaconStateBase := &pb.BeaconState{}
if err := preBeaconStateBase.UnmarshalSSZ(preBeaconStateFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, preBeaconStateBase.UnmarshalSSZ(preBeaconStateFile), "Failed to unmarshal")
preBeaconState, err := stateTrie.InitializeFromProto(preBeaconStateBase)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
// If the post.ssz is not present, it means the test should fail on our end.
postSSZFilepath, err := bazel.Runfile(path.Join(testsFolderPath, folder.Name(), "post.ssz"))
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.
beaconState, err := blocks.ProcessBlockHeaderNoVerify(preBeaconState, block)
if postSSZExists {
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
require.NoError(t, err)
postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
postBeaconState := &pb.BeaconState{}
if err := postBeaconState.UnmarshalSSZ(postBeaconStateFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateFile), "Failed to unmarshal")
if !proto.Equal(beaconState.CloneInnerState(), postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.CloneInnerState(), postBeaconState)
t.Log(diff)

View File

@@ -19,6 +19,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"gopkg.in/d4l3k/messagediff.v1"
)
@@ -27,48 +28,32 @@ func init() {
}
func runBlockProcessingTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "sanity/blocks/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
helpers.ClearCache()
preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
beaconStateBase := &pb.BeaconState{}
if err := beaconStateBase.UnmarshalSSZ(preBeaconStateFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, beaconStateBase.UnmarshalSSZ(preBeaconStateFile), "Failed to unmarshal")
beaconState, err := stateTrie.InitializeFromProto(beaconStateBase)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
file, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "meta.yaml")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
metaYaml := &SanityConfig{}
if err := testutil.UnmarshalYaml(file, metaYaml); err != nil {
t.Fatalf("Failed to Unmarshal: %v", err)
}
require.NoError(t, testutil.UnmarshalYaml(file, metaYaml), "Failed to Unmarshal")
var transitionError error
for i := 0; i < metaYaml.BlocksCount; i++ {
filename := fmt.Sprintf("blocks_%d.ssz", i)
blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), filename)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{}
if err := block.UnmarshalSSZ(blockFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, block.UnmarshalSSZ(blockFile), "Failed to unmarshal")
beaconState, transitionError = state.ExecuteStateTransition(context.Background(), beaconState, block)
if transitionError != nil {
break
@@ -90,14 +75,10 @@ func runBlockProcessingTest(t *testing.T, config string) {
}
postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
postBeaconState := &pb.BeaconState{}
if err := postBeaconState.UnmarshalSSZ(postBeaconStateFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateFile), "Failed to unmarshal")
if !proto.Equal(beaconState.InnerStateUnsafe(), postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.InnerStateUnsafe(), postBeaconState)

View File

@@ -1,35 +1,34 @@
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"
)
func runDepositTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/deposit/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
folderPath := path.Join(testsFolderPath, folder.Name())
depositFile, err := testutil.BazelFileBytes(folderPath, "deposit.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
deposit := &ethpb.Deposit{}
if err := deposit.UnmarshalSSZ(depositFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, deposit.UnmarshalSSZ(depositFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{Deposits: []*ethpb.Deposit{deposit}}
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessDeposits)
testutil.RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, state *state.BeaconState, b *ethpb.SignedBeaconBlock) (*state.BeaconState, error) {
return blocks.ProcessDeposits(ctx, state, b)
})
})
}
}

View File

@@ -8,25 +8,20 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func runProposerSlashingTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/proposer_slashing/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
folderPath := path.Join(testsFolderPath, folder.Name())
proposerSlashingFile, err := testutil.BazelFileBytes(folderPath, "proposer_slashing.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
proposerSlashing := &ethpb.ProposerSlashing{}
if err := proposerSlashing.UnmarshalSSZ(proposerSlashingFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, proposerSlashing.UnmarshalSSZ(proposerSlashingFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{ProposerSlashings: []*ethpb.ProposerSlashing{proposerSlashing}}
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessProposerSlashings)

View File

@@ -8,25 +8,20 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func runVoluntaryExitTest(t *testing.T, config string) {
if err := spectest.SetConfig(t, config); err != nil {
t.Fatal(err)
}
require.NoError(t, spectest.SetConfig(t, config))
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/voluntary_exit/pyspec_tests")
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
folderPath := path.Join(testsFolderPath, folder.Name())
exitFile, err := testutil.BazelFileBytes(folderPath, "voluntary_exit.ssz")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
voluntaryExit := &ethpb.SignedVoluntaryExit{}
if err := voluntaryExit.UnmarshalSSZ(exitFile); err != nil {
t.Fatalf("Failed to unmarshal: %v", err)
}
require.NoError(t, voluntaryExit.UnmarshalSSZ(exitFile), "Failed to unmarshal")
body := &ethpb.BeaconBlockBody{VoluntaryExits: []*ethpb.SignedVoluntaryExit{voluntaryExit}}
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessVoluntaryExits)

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,9 @@ 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",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1: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)
@@ -351,14 +351,12 @@ func unslashedAttestingIndices(state *stateTrie.BeaconState, atts []*pb.PendingA
}
attestingIndices := attestationutil.AttestingIndices(att.AggregationBits, committee)
// Create a set for attesting indices
set := make([]uint64, 0, len(attestingIndices))
for _, index := range attestingIndices {
if !seen[index] {
set = append(set, index)
setIndices = append(setIndices, index)
}
seen[index] = true
}
setIndices = append(setIndices, set...)
}
// Sort the attesting set indices by increasing order.
sort.Slice(setIndices, func(i, j int) bool { return setIndices[i] < setIndices[j] })

View File

@@ -6,6 +6,7 @@ import (
fuzz "github.com/google/gofuzz"
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 TestFuzzFinalUpdates_10000(t *testing.T) {
@@ -15,9 +16,8 @@ func TestFuzzFinalUpdates_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(base)
s, err := beaconstate.InitializeFromProtoUnsafe(base)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
_, err = ProcessFinalUpdates(s)
_ = err
}
}

View File

@@ -1,16 +1,19 @@
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"
)
func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
@@ -18,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},
}
@@ -38,14 +41,10 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
}
state, err := state.InitializeFromProto(base)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
indices, err := unslashedAttestingIndices(state, atts)
if err != nil {
t.Fatal(err)
}
indices, err := epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices)-1; i++ {
if indices[i] >= indices[i+1] {
t.Error("sorted indices not sorted or duplicated")
@@ -56,17 +55,11 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
slashedValidator := indices[0]
validators = state.Validators()
validators[slashedValidator].Slashed = true
if err = state.SetValidators(validators); err != nil {
t.Fatal(err)
}
indices, err = unslashedAttestingIndices(state, atts)
if err != nil {
t.Fatal(err)
}
require.NoError(t, state.SetValidators(validators))
indices, err = epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices); i++ {
if indices[i] == slashedValidator {
t.Errorf("Slashed validator %d is not filtered", slashedValidator)
}
assert.NotEqual(t, slashedValidator, indices[i], "Slashed validator %d is not filtered", slashedValidator)
}
}
@@ -75,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},
}
@@ -94,14 +87,10 @@ func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) {
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
}
state, err := state.InitializeFromProto(base)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
indices, err := unslashedAttestingIndices(state, atts)
if err != nil {
t.Fatal(err)
}
indices, err := epoch.UnslashedAttestingIndices(state, atts)
require.NoError(t, err)
for i := 0; i < len(indices)-1; i++ {
if indices[i] >= indices[i+1] {
@@ -117,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,
@@ -144,18 +133,12 @@ func TestAttestingBalance_CorrectBalance(t *testing.T) {
Balances: balances,
}
state, err := state.InitializeFromProto(base)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
balance, err := AttestingBalance(state, atts)
if err != nil {
t.Fatal(err)
}
balance, err := epoch.AttestingBalance(state, atts)
require.NoError(t, err)
wanted := 256 * params.BeaconConfig().MaxEffectiveBalance
if balance != wanted {
t.Errorf("wanted balance: %d, got: %d", wanted, balance)
}
assert.Equal(t, wanted, balance)
}
func TestBaseReward_AccurateRewards(t *testing.T) {
@@ -176,17 +159,10 @@ func TestBaseReward_AccurateRewards(t *testing.T) {
Balances: []uint64{tt.a},
}
state, err := state.InitializeFromProto(base)
if err != nil {
t.Fatal(err)
}
c, err := BaseReward(state, 0)
if err != nil {
t.Fatal(err)
}
if c != tt.c {
t.Errorf("BaseReward(%d) = %d, want = %d",
tt.a, c, tt.c)
}
require.NoError(t, err)
c, err := epoch.BaseReward(state, 0)
require.NoError(t, err)
assert.Equal(t, tt.c, c, "epoch.BaseReward(%d)", tt.a)
}
}
@@ -198,17 +174,11 @@ func TestProcessSlashings_NotSlashed(t *testing.T) {
Slashings: []uint64{0, 1e9},
}
s, err := state.InitializeFromProto(base)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessSlashings(s)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
newState, err := epoch.ProcessSlashings(s)
require.NoError(t, err)
wanted := params.BeaconConfig().MaxEffectiveBalance
if newState.Balances()[0] != wanted {
t.Errorf("Wanted slashed balance: %d, got: %d", wanted, newState.Balances()[0])
}
assert.Equal(t, wanted, newState.Balances()[0], "Unexpected slashed balance")
}
func TestProcessSlashings_SlashedLess(t *testing.T) {
@@ -282,83 +252,48 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
t.Run(string(i), func(t *testing.T) {
original := proto.Clone(tt.state)
s, err := state.InitializeFromProto(tt.state)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessSlashings(s)
if err != nil {
t.Fatal(err)
}
if newState.Balances()[0] != tt.want {
t.Errorf(
"ProcessSlashings({%v}) = newState; newState.Balances[0] = %d; wanted %d",
original,
newState.Balances()[0],
tt.want,
)
}
require.NoError(t, err)
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])
})
}
}
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
if err := s.SetEth1DataVotes([]*ethpb.Eth1Data{}); err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetEth1DataVotes([]*ethpb.Eth1Data{}))
balances := s.Balances()
balances[0] = 31.75 * 1e9
balances[1] = 31.74 * 1e9
if err := s.SetBalances(balances); err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetBalances(balances))
slashings := s.Slashings()
slashings[ce] = 0
if err := s.SetSlashings(slashings); err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetSlashings(slashings))
mixes := s.RandaoMixes()
mixes[ce] = []byte{'A'}
if err := s.SetRandaoMixes(mixes); err != nil {
t.Fatal(err)
}
newS, err := ProcessFinalUpdates(s)
if err != nil {
t.Fatal(err)
}
require.NoError(t, s.SetRandaoMixes(mixes))
newS, err := epoch.ProcessFinalUpdates(s)
require.NoError(t, err)
// Verify effective balance is correctly updated.
if newS.Validators()[0].EffectiveBalance != params.BeaconConfig().MaxEffectiveBalance {
t.Errorf("effective balance incorrectly updated, got %d", s.Validators()[0].EffectiveBalance)
}
if newS.Validators()[1].EffectiveBalance != 31*1e9 {
t.Errorf("effective balance incorrectly updated, got %d", s.Validators()[1].EffectiveBalance)
}
assert.Equal(t, params.BeaconConfig().MaxEffectiveBalance, newS.Validators()[0].EffectiveBalance, "Effective balance incorrectly updated")
assert.Equal(t, uint64(31*1e9), newS.Validators()[1].EffectiveBalance, "Effective balance incorrectly updated")
// Verify slashed balances correctly updated.
if newS.Slashings()[ce] != newS.Slashings()[ne] {
t.Errorf("wanted slashed balance %d, got %d",
newS.Slashings()[ce],
newS.Slashings()[ne])
}
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.
if len(newS.HistoricalRoots()) != 1 {
t.Errorf("wanted slashed balance %d, got %d", 1, len(newS.HistoricalRoots()[ce]))
}
if newS.CurrentEpochAttestations() == nil {
t.Error("nil value stored in current epoch attestations instead of empty slice")
}
assert.Equal(t, 1, len(newS.HistoricalRoots()), "Unexpected slashed balance")
assert.NotNil(t, newS.CurrentEpochAttestations(), "Nil value stored in current epoch attestations instead of empty slice")
}
func TestProcessRegistryUpdates_NoRotation(t *testing.T) {
@@ -372,33 +307,24 @@ 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)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessRegistryUpdates(state)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
if validator.ExitEpoch != params.BeaconConfig().MaxSeedLookahead {
t.Errorf("Could not update registry %d, wanted exit slot %d got %d",
i, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch)
}
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch, "Could not update registry %d", i)
}
}
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)
if err != nil {
t.Error(err)
}
require.NoError(t, err)
for i := uint64(0); i < limit+10; i++ {
base.Validators = append(base.Validators, &ethpb.Validator{
ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch,
@@ -407,16 +333,12 @@ func TestProcessRegistryUpdates_EligibleToActivate(t *testing.T) {
})
}
state, err := state.InitializeFromProto(base)
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(state)
newState, err := ProcessRegistryUpdates(state)
if err != nil {
t.Error(err)
}
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
if validator.ActivationEligibilityEpoch != currentEpoch+1 {
t.Errorf("Could not update registry %d, wanted activation eligibility epoch %d got %d",
i, currentEpoch, validator.ActivationEligibilityEpoch)
}
assert.Equal(t, currentEpoch+1, validator.ActivationEligibilityEpoch, "Could not update registry %d, unexpected activation eligibility epoch", i)
if uint64(i) < limit && validator.ActivationEpoch != helpers.ActivationExitEpoch(currentEpoch) {
t.Errorf("Could not update registry %d, validators failed to activate: wanted activation epoch %d, got %d",
i, helpers.ActivationExitEpoch(currentEpoch), validator.ActivationEpoch)
@@ -437,21 +359,14 @@ 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)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessRegistryUpdates(state)
if err != nil {
t.Error(err)
}
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
if validator.ExitEpoch != params.BeaconConfig().MaxSeedLookahead {
t.Errorf("Could not update registry %d, wanted exit slot %d got %d",
i, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch)
}
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead, validator.ExitEpoch, "Could not update registry %d, unexpected exit slot", i)
}
}
@@ -468,30 +383,23 @@ 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)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessRegistryUpdates(state)
if err != nil {
t.Error(err)
}
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
if validator.ExitEpoch != params.BeaconConfig().MaxSeedLookahead+1 {
t.Errorf("Could not update registry %d, wanted exit slot %d got %d",
i, params.BeaconConfig().MaxSeedLookahead+1, validator.ExitEpoch)
}
assert.Equal(t, params.BeaconConfig().MaxSeedLookahead+1, validator.ExitEpoch, "Could not update registry %d, unexpected exit slot", i)
}
}
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,
@@ -500,28 +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)
if err != nil {
t.Fatal(err)
}
newState, err := ProcessRegistryUpdates(state)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(state)
require.NoError(t, err)
for i, validator := range newState.Validators() {
if validator.ExitEpoch != exitEpoch {
t.Errorf("Could not update registry %d, wanted exit slot %d got %d",
i,
exitEpoch,
validator.ExitEpoch,
)
}
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 uint64, validatorCount uint64) *state.BeaconState {
validators := make([]*ethpb.Validator, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
@@ -547,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

@@ -46,6 +46,8 @@ go_test(
"//shared/mathutil: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",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",

View File

@@ -33,6 +33,9 @@ func ProcessAttestations(
var err error
for _, a := range append(state.PreviousEpochAttestations(), state.CurrentEpochAttestations()...) {
if a.InclusionDelay == 0 {
return nil, nil, errors.New("attestation with inclusion delay of 0")
}
v.IsCurrentEpochAttester, v.IsCurrentEpochTargetAttester, err = AttestedCurrentEpoch(state, a)
if err != nil {
traceutil.AnnotateError(span, err)

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