Compare commits

...

217 Commits

Author SHA1 Message Date
terence tsao
74cf2320ad Altair: Split no verify functions in own file (#8747)
* Split transition no verify functions in its own file

* Remove redeclared functions

* Go fmt

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

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

* fix rc

* try again

* Revert "try again"

This reverts commit 70ff7658b7.

* fix fuzz

* Update shared/bls/blst/BUILD.bazel

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

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

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

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

* strong password defined elsewhere- removed

* Update validator/rpc/accounts_test.go

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

* added PublicKeys Nil test case

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

* goimports -w root

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

* removed unneeded comment

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

* gofmt

* unrelated files

* unrelated files

* unrelatedfiles restored

* revert unrelated files

* changed the last ss

* adding slashign endpoints

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

* added import slashing unit test

* clean up

* remove less

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

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

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

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

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

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

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

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

* camelCase Proto

* update slashing_protection_json

* update proto

* register in validator/rpc/gateway

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

* round trip test

* gofmt

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

* Update validator/rpc/slashing.go

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

* gaz

* deprecate flag

* remove source builds of herumi

* remove

* Revert "remove source builds of herumi"

This reverts commit ac7dd133ed.

* disable blst

* remove herumi hard requirement from fuzz

* restrict viz, ensure all deps removed from fuzz

* remove source builds

* add back opts

* add back herumi initialization

* Revert "add back opts"

This reverts commit ad9b409b8a.

* Revert "remove source builds"

This reverts commit b78ee30dba.

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

This reverts commit 65d951da93.

* Revert "remove herumi hard requirement from fuzz"

This reverts commit ad92191d81.

* redundant

* add lock for rand generation

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

* Add LatestWeakSubjectivityEpoch method

* ParseWeakSubjectivityInputString helper

* switch to Checkpoint

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

* Add LatestWeakSubjectivityEpoch method

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

* removed redundant check

* separate createwallet into imported and derived. Recover is derived

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

* so proto does CamelCase!

* fixed issues related to unit testing

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

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

* added skipMnemonic25thword support and unit test

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

Proper naming convention

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

* ran goimports,changed variable to SkipMnemonic_25ThWord

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

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

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

* added unit test for strong password on recover

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

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

* Update validator/rpc/wallet.go

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

* goimports -w on root proto

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

* language should be case insensitive

* need to goimports before update protobuf scripts

* Update validator/rpc/wallet.go

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

* Update validator/rpc/wallet.go

comments need to be consistant

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

* Update validator/rpc/wallet_test.go

consistent comments

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

* fix comments

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

* defer call to set the writePassword flag on web boarding

* gofmt

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

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

* revert beacon messages.pb.go

* revert unrelated files

* revert unrelated files

* revert unrelated files

* unlreated files

* restored the imports

* Update validator/rpc/wallet_test.go

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

* Nishant's suggestion on cache reset

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

* Return beacon state

* Return nil

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

* apply #8704 change

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

* go mod tidy

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

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

* add more param changes

* more cleanup

* fix order of operations

* comments

* remove redundant declaration

* clean up better

* fix up

* victor's review

* disable mesh scoring

* disable mesh scoring

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

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

* strong password defined elsewhere- removed

* Update validator/rpc/accounts_test.go

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

* added PublicKeys Nil test case

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

* goimports -w root

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

* removed unneeded comment

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

* gofmt

* unrelated files

* unrelated files

* unrelatedfiles restored

* revert unrelated files

* changed the last ss

* restore imports

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

* implement ComputeWeakSubjectivityCheckptEpoch

* remove helper func

* fix unit tests

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

* split func

* keysplit tool

* gaz/viz

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

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

* change log formatting

* Revert "change log formatting"

This reverts commit b610fd67ed.

* Revert "Break long lines in beacon chain package"

This reverts commit 53215fdcde.

* wrap lines over 160

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

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

* extracted StateFetcher

* StateFetcher tests

* extract beacon state creation option and fix state tests

* add comment to StateFetcher

* register the server

* implement grpc function

* test ToProto

* gRPC function test with mock state fetcher

* reduce visibility of packages

* add missing error assertion

* removed unused code

* overwrite config name

* gzl

* Fix service fields

* rename StateFetcher to Provider

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

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

* adjust code to new v0 interfaces

* interface/struct naming changes

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

* Add only has bestChild case

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

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

* Apply suggestions from code review

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

* randomized backoff period on discovery

* fix signature

* gazelle

* deterministic randg

* define ComponentRunner

* update ETH1 node

* extrace BootNode

* add logger

* remove refs to t

* gazelle

* update BeaconNode

* parametrize tests

* update log formatting

* update ValidatorNode

* remove redundant test id from params

* decrease delta

* move BootNode

* update BootNode

* revert params

* update SlasherNode

* mask unused param

* update helpers

* update test runner

* go mod tidy

* remove unused fields

* re-arrange tests

* extract sync into its own method

* gazelle

* BeaconNode

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

* remove deprecated method

* BeaconNodes -> BeaconNodeSet

* make sure that slasher is required component

* update StartBeaconNodeSet() and StartValidatorNodeSet()

* update SlasherNodeSet

* gazelle

* update connectivity tests

* Nishant's suggestion

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

* Add error to return signature

* Remove SetCurrentEpochAttestations and SetPreviousEpochAttestations

* Fix tests

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

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

* update ETH1 node

* extrace BootNode

* add logger

* remove refs to t

* gazelle

* update BeaconNode

* parametrize tests

* update log formatting

* update ValidatorNode

* remove redundant test id from params

* decrease delta

* move BootNode

* update BootNode

* revert params

* update SlasherNode

* mask unused param

* update helpers

* update test runner

* go mod tidy

* remove unused fields

* re-arrange tests

* extract sync into its own method

* gazelle

* BeaconNode

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

* remove deprecated method

* BeaconNodes -> BeaconNodeSet

* make sure that slasher is required component

* update StartBeaconNodeSet() and StartValidatorNodeSet()

* update SlasherNodeSet

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

* unstuck!

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

* add deprecation warning

* Radek's suggestion on naming

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

* gofmt

* update types

* update types

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

* types/types.go

* BootNode

* gofmt

* remove unused argument

* remove redundant comment

* add deprecation comment

* types comment

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

* fuzz wrapper fixes

* more deepsource

* more shell

* export

* shell

* combine func params, fix go deep source issues

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

* gzl

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

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

* Rename to Uint64ListRootWithRegistryLimit

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

* Setup test with a deposit cache

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

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

* extracted StateFetcher

* StateFetcher tests

* extract beacon state creation option and fix state tests

* add comment to StateFetcher

* remove empty line

* overwrite config name

* fix field names

* remove FillRootsNaturalOpt helper

* reduce statefetcher package visibility

* gzl

* add missing error assertion

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

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

* Refactor to reuse the same code

* gofmt

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

* gaz

* Update generated code

* First pass inclusion of using baked states

* more emptypb fixes

* remove testnet genesis files, only embed mainnet

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

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

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

* gofmt

* more clear error

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

* viz

* test for SaveGenesisData

* More genesis db method tests

* Merge

* Minor tweaks, lint, fmt, etc

* Add more test to genesis db methods

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

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

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

* PR feedback

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

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

* fmt.Errorf works better for nil errors

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

* Typos

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

* Build.bazel

* Remove unused RootsArrayHashTreeRoot

* Revert "Remove unused RootsArrayHashTreeRoot"

This reverts commit bf0bda30d1.

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

* return plain errors from helper functions

* change errors to lowercase in node

* correct test expectations

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

* Register flag everywhere

* gofmt

* Apply suggestions from code review

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

* Update shared/params/testnet_prater_config.go

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

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

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

* Gazelle

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

* fix failing keymanager test

* keymanager tests

* define RemoteKeymanager interface

* WaitForActivation tests

* gzl

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

* change parameter type to ReadOnlyBeaconState

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

* proper implementation

* fix WaitForActivation tests

* HandleKeyReload tests

* runner tests

* do not reuse log hook between tests

* gzl

* Drop unnecessary use of the blank identifier

* move mock_validator to testutil package

* Reorganize validator client package

* reduce package visibility

* revert account changes

* gzl

* describe nil parameter

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

* gaz

* Update generated code

* more emptypb fixes

* gaz

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

* shorter pruning

* pass all pruning tests

* passing tests

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

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

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

* Fix tests

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

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

* Found a better place where to update the counters

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

* remove all enable disable code

* fix broken build

* fix more tests

* fix broken tests

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

* better alisgn struct field

* more tests

* cleanup

* simplify expressions

* add benchmarks

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

* gaz

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

* V1AttToV1Alpha1 migration

* Implementation plus happy path test

* fix root variable names

* Invalid attestation test

* gzl

* mod tidy

* use a single append to concatenate two slices

* remove outdated comment from attestation processing

* invoke ProcessAttestationNoVerifySignature when validating attestations

* implement missing PoolMock members

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

* Commentary

* Update test to follow the full code path

* gofmt and goimports

* manual imports fixes

* Apply suggestions from code review

typo fixes

* Remove redundant handleAccountsChanged and chan. Thanks @nisdas

* var sub = to sub :=

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

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

* preston's comments

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

* fix broken test

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

* Gazelle

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

* gaz

* imports

* slasher img

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

* comments

* gaz

* gaz ignored file

* build

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

* add test

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

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

* Comment

* First take at clean up

* Completed interfaces

* Fix build and test

* Reordering interfaces

* Add build.bazel

* Add build.bazel

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

* imports spacing

* more import fix

* edit build file

* e2e viz

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

* imports

* more imports

* e2e viz

* alias

* use native alias

* add actual

* fix macro

* work on fix e2e

* add viz

* gaz

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

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

* Limit password occurrences

* Make only 1 occurence of 'strongPass'

* Limit testMnemonic occurrences

* Limit expected epoch error messages

* Rename errors and use constant

* Update bazel dependencies

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

This reverts commit a92b20d2bb.

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

* gofmt

* apply suggestion

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

* SubmitVoluntaryExit

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

* rest of tests

* gzl

* test block hydration

* compare roots

* gzl

* compare exit roots

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

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

* gazelle build

* remove less! why there?

* fixed errors import

* fixed errors import

* unit tested

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

* deleted the comment

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

* Fix style issues

* Print pubkeys alongside the validator indexes

* Improve list-indices output

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

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

* Also update go.mod

* rm go.sum then run go mod tidy

* go mod tidy with go 1.16

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

* Go mod tidy

* Gazelle

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

* gzl

* remove migration test rule

* fix BUILD file formatting

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

* Updated validator to use Ordered graffiti

* Track graffiti ordered index in db

* Update `ordered` to only emit each graffiti once

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

* Comment formatting

* Update beacon-chain/sync/validate_beacon_blocks.go

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

* add test

* gaz

* victor's review

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

* remove listening for changes from wallet creation

* goimports

* test fix

* more goimports

* listen for changes when initializing wallet through gRPC

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

* implement ListPoolAttesterSlashings

* add comments to bool arguments

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

* Add regression testing

* make it double just in case

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

* Fix build: remove unused imports

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

* New line

* New line

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

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

* implementation

* gofmt

* gzl

* Use migration package for slashing mapping

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

* First take at fixing tests

* Clean up e2e, fuzz... etc

* Fix new lines

* Update beacon-chain/cache/proposer_indices_test.go

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

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

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

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

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

* Update validator/graffiti/parse_graffiti_test.go

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

* Raul's feedback

* Fix downcast int -> uint64

* Victor's feedback

* Replace validator id with validator index

* Replace validator id with validator index

* Typo

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

* First take at fixing tests

* Clean up e2e, fuzz... etc

* Fix new lines

* Update beacon-chain/cache/proposer_indices_test.go

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

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

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

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

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

* Update validator/graffiti/parse_graffiti_test.go

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

* Raul's feedback

* Fix downcast int -> uint64

* Victor's feedback

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

* another fix

* reset gw files

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

* Add outline for debug endpoints

* Fix comment

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

* go fmt

* Change message text

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

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

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

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

* Go fmt

* Update validator pkg

* Fix e2e

* Happy fuzz tests

* Sync with upstream ethereumapi

* Go mod tidy

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

* Update test

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

* Update shared/prometheus/service.go

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

* Update tests

* Apply suggestions from code review

* Update shared/prometheus/service_test.go

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

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

* remove commented code

* extract methods

* migration logic tested up

* migration up and down tests

* Update validator/db/kv/attester_protection.go

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

* added in pruning and batched migrations

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

* name

* comment

* change back

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

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

* implement StateByStateRoot

* initial implementation

* tests

* refactor code into smaller functions

* gzl

* simplify StateByStateRoot and tests

* Nishant's feedback

* gzl

* handle error in test

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

* First take

* Apply for validator

* Use constant

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

* deprecate disable majority vote flag

* remove eth1dataVoteCache

* remove outdated methods

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

* Annotate attestation spans

* gaz

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

* update eth2-types deps

* update protobufs

* update shared/*

* fix testutil/state

* update beacon-chain/state

* update beacon-chain/db

* update tests

* fix test

* update beacon-chain/core

* update beacon-chain/blockchain

* update beacon-chain/cache

* beacon-chain/forkchoice

* update beacon-chain/operations

* update beacon-chain/p2p

* update beacon-chain/rpc

* update sync/initial-sync

* update deps

* update deps

* go fmt

* update beacon-chain/sync

* update endtoend/

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

* update slasher code

* udpate tools/

* update validator/

* update fastssz

* fix build

* fix test building

* update tests

* update ethereumapis deps

* fix tests

* update state/stategen

* fix build

* fix test

* add FarFutureSlot

* go imports

* Radek's suggestions

* Ivan's suggestions

* type conversions

* Nishant's suggestions

* add more tests to rpc_send_request

* fix test

* clean up

* fix conflicts

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

* revert bazelrc

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

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

* Added newline based on the PR checks

* Update shared/logutil/logutil.go

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

* Update shared/logutil/logutil.go

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

* Gazelle

* Update shared/logutil/logutil.go

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

* Update shared/logutil/logutil.go

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

* added unit tests

* updated one test case

* added logutil_test.go unit test cases

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

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

* Fix test

* Fix test

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

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

* add programmatic voluntary exit

* add exit all flag

* test

* lint

* add multiple exits test

* fix test

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

* Increase Validation Queue (#8431)

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

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

* Add a debug log to show duration

* Autofix issues in 1 file

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

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

* Add Mutex and Block Profiling (#8435)

* Implement GetStateRoot in the beacon API (#8402)

* update ethereumapis dependency

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

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

* On Block Cleanup (#8438)

* Beacon API: update GetStateRoot  (#8437)

* Address various feedbacks

* Gaz

* More nil check

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

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

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

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

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

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

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

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

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

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

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

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

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

* Update shared/logutil/logutil.go

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

* gaz

* fuzz

* add dep viz

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

* Restore timeSinceSlotStart

* Renamed fields

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

* merge from dev

* use safe pending attestation records struct

* fix build, use atomic bool

* Add deadline checks to CheckSlashableAttestation

* Go fmt

* Add test for in-progress log

* GoDocs

* Rename pending attestation records to queued attestation records

* rename and add commentary on log

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

This reverts commit d121b19145.

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

* fix name in test

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

* Comment

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

* Gaz

* More nil check

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

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

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

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

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

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

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

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

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

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

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

* span

* initial implementation

* introduce stategen Service interface and MockService

* Include AddStateForSlot function in the mock service

* return states from mock

* add GenesisState to POWChain mock

* populate roots in helper state

* initialize Slot when creating helper state

* tests

* code refactor - extract helper functions

* gzl

* use SetSlot in tests

* handle SetSlot error

* use new testutil's NewBeaconState

* gzl

* go mod tidy

* rename Service to StateManager

* move regex check to helper

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

* Autofix issues in 1 file

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

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

* add exit all flag

* test

* lint

* add multiple exits test

* fix test

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

* Fix test

* Fix test

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

* update

* Ran regenerate.sh

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

* Fixes

* gaz

* Fix test

* Add UnexportedOnly function

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

* Revert back to process epoch

* Use processed state

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

* clean up

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

* Add matching getters

* Fix tests

* Update tests

* Fix test

* Remove read locks

* Typo

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

* terence's review

* add test

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

* Provide TLS certificate to gRPC gateway

* Provide TLS certificate to gRPC gateway

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

* Move finalized imply justified up

* Fix resolve error

* Use invert feature flag

* Make diff easier to review

* Line

* Typo

* Fix condition

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

* update deps

* update protos/*

* update deps

* reset protos

* update protos

* update shared/params/config

* update protos

* update /shared

* update shared/slotutil and shared/testutil

* update beacon-chain/core/helpers

* updates beacon-chain/state

* update beacon-chain/forkchoice

* update beacon-chain/blockchain

* update beacon-chain/cache

* update beacon-chain/core

* update beacon-chain/db

* update beacon-chain/node

* update beacon-chain/p2p

* update beacon-chain/rpc

* update beacon-chain/sync

* go mod tidy

* make sure that beacon-chain build suceeds

* go fmt

* update e2e tests

* update slasher

* remove redundant alias

* update validator

* gazelle

* fix build errors in unit tests

* go fmt

* update deps

* update fuzz/BUILD.bazel

* fix unit tests

* more unit test fixes

* fix blockchain UTs

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

* Use the correct version of bls-eth-go-binary
2021-02-09 01:44:27 +00:00
terence tsao
fed65122fe Use EnableNextSlotStateCache few more places (#8398) 2021-02-08 13:11:21 -08:00
977 changed files with 28360 additions and 16796 deletions

View File

@@ -39,16 +39,15 @@ build --define kafka_enabled=false
test --define kafka_enabled=false
run --define kafka_enabled=false
# Enable blst by default, we use a config so that our fuzzer stops complaining.
build --config=blst_enabled
test --config=blst_enabled
run --config=blst_enabled
build --define blst_disabled=false
test --define blst_disabled=false
run --define blst_disabled=false
build:kafka_enabled --define kafka_enabled=true
build:kafka_enabled --define gotags=kafka_enabled
build:blst_enabled --define blst_enabled=true
build:blst_enabled --define gotags=blst_enabled
build:blst_disabled --define blst_disabled=true
build:blst_disabled --define gotags=blst_disabled
# Release flags
build:release --compilation_mode=opt
@@ -84,7 +83,7 @@ build:fuzz --linkopt -Wl,--no-as-needed
build:fuzz --define=gc_goopts=-d=libfuzzer,checkptr
build:fuzz --run_under=//tools:fuzz_wrapper
build:fuzz --compilation_mode=opt
build:fuzz --define=blst_enabled=false
build:fuzz --define=blst_disabled=true
test:fuzz --local_test_jobs="HOST_CPUS*.5"

View File

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

View File

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

View File

@@ -60,10 +60,10 @@ bazel_skylib_workspace()
http_archive(
name = "bazel_gazelle",
sha256 = "1f4fc1d91826ec436ae04833430626f4cc02c20bb0a813c0c2f3c4c421307b1d",
strip_prefix = "bazel-gazelle-e368a11b76e92932122d824970dc0ce5feb9c349",
sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f",
urls = [
"https://github.com/bazelbuild/bazel-gazelle/archive/e368a11b76e92932122d824970dc0ce5feb9c349.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
],
)
@@ -89,10 +89,10 @@ http_archive(
# nogo check fails for certain third_party dependencies.
"//third_party:io_bazel_rules_go.patch",
],
sha256 = "dbf5a9ef855684f84cac2e7ae7886c5a001d4f66ae23f6904da0faaaef0d61fc",
sha256 = "7c10271940c6bce577d51a075ae77728964db285dac0a46614a7934dc34303e6",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.11/rules_go-v0.24.11.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.11/rules_go-v0.24.11.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.26.0/rules_go-v0.26.0.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.26.0/rules_go-v0.26.0.tar.gz",
],
)
@@ -156,7 +156,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
go_register_toolchains(
go_version = "1.15.7",
go_version = "1.16",
nogo = "@//:nogo",
)

View File

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

View File

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

View File

@@ -27,7 +27,6 @@ go_library(
deps = [
"//beacon-chain/cache:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
@@ -35,7 +34,6 @@ go_library(
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/filters:go_default_library",
"//beacon-chain/flags:go_default_library",
"//beacon-chain/forkchoice:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
@@ -43,8 +41,10 @@ go_library(
"//beacon-chain/operations/voluntaryexits:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
@@ -59,6 +59,7 @@ go_library(
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
@@ -82,6 +83,7 @@ go_test(
"checktags_test.go",
"head_test.go",
"info_test.go",
"init_test.go",
"metrics_test.go",
"process_attestation_test.go",
"process_block_test.go",
@@ -128,6 +130,7 @@ go_test(
srcs = [
"chain_info_norace_test.go",
"checktags_test.go",
"init_test.go",
"receive_block_test.go",
"service_norace_test.go",
],

View File

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

View File

@@ -13,7 +13,7 @@ import (
func TestHeadSlot_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: beaconDB,
cfg: &Config{BeaconDB: beaconDB},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -24,9 +24,8 @@ func TestHeadSlot_DataRace(t *testing.T) {
func TestHeadRoot_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: beaconDB,
head: &head{root: [32]byte{'A'}},
stateGen: stategen.New(beaconDB),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{root: [32]byte{'A'}},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -38,9 +37,8 @@ func TestHeadRoot_DataRace(t *testing.T) {
func TestHeadBlock_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: beaconDB,
head: &head{block: &ethpb.SignedBeaconBlock{}},
stateGen: stategen.New(beaconDB),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{block: &ethpb.SignedBeaconBlock{}},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -52,8 +50,7 @@ func TestHeadBlock_DataRace(t *testing.T) {
func TestHeadState_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
beaconDB: beaconDB,
stateGen: stategen.New(beaconDB),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))

View File

@@ -6,11 +6,12 @@ import (
"time"
"github.com/gogo/protobuf/proto"
types "github.com/prysmaticlabs/eth2-types"
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/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -103,10 +104,10 @@ func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
func TestHeadSlot_CanRetrieve(t *testing.T) {
c := &Service{}
s, err := state.InitializeFromProto(&pb.BeaconState{})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c.head = &head{slot: 100, state: s}
assert.Equal(t, uint64(100), c.HeadSlot())
assert.Equal(t, types.Slot(100), c.HeadSlot())
}
func TestHeadRoot_CanRetrieve(t *testing.T) {
@@ -119,7 +120,7 @@ func TestHeadRoot_CanRetrieve(t *testing.T) {
func TestHeadRoot_UseDB(t *testing.T) {
beaconDB := testDB.SetupDB(t)
c := &Service{beaconDB: beaconDB}
c := &Service{cfg: &Config{BeaconDB: beaconDB}}
c.head = &head{root: params.BeaconConfig().ZeroHash}
b := testutil.NewBeaconBlock()
br, err := b.Block.HashTreeRoot()
@@ -135,7 +136,7 @@ func TestHeadRoot_UseDB(t *testing.T) {
func TestHeadBlock_CanRetrieve(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
s, err := state.InitializeFromProto(&pb.BeaconState{})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c := &Service{}
c.head = &head{block: b, state: s}
@@ -146,7 +147,7 @@ func TestHeadBlock_CanRetrieve(t *testing.T) {
}
func TestHeadState_CanRetrieve(t *testing.T) {
s, err := state.InitializeFromProto(&pb.BeaconState{Slot: 2, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{Slot: 2, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -163,7 +164,7 @@ func TestGenesisTime_CanRetrieve(t *testing.T) {
func TestCurrentFork_CanRetrieve(t *testing.T) {
f := &pb.Fork{Epoch: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Fork: f})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{Fork: f})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -188,7 +189,7 @@ func TestGenesisValidatorRoot_CanRetrieve(t *testing.T) {
c := &Service{}
assert.Equal(t, [32]byte{}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
s, err := state.InitializeFromProto(&pb.BeaconState{GenesisValidatorsRoot: []byte{'a'}})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{GenesisValidatorsRoot: []byte{'a'}})
require.NoError(t, err)
c.head = &head{state: s}
assert.Equal(t, [32]byte{'a'}, c.GenesisValidatorRoot(), "Did not get correct genesis validator root")
@@ -202,7 +203,7 @@ func TestHeadETH1Data_Nil(t *testing.T) {
func TestHeadETH1Data_CanRetrieve(t *testing.T) {
d := &ethpb.Eth1Data{DepositCount: 999}
s, err := state.InitializeFromProto(&pb.BeaconState{Eth1Data: d})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{Eth1Data: d})
require.NoError(t, err)
c := &Service{}
c.head = &head{state: s}
@@ -277,7 +278,21 @@ func TestService_HeadGenesisValidatorRoot(t *testing.T) {
}
func TestService_ProtoArrayStore(t *testing.T) {
c := &Service{forkChoiceStore: protoarray.New(0, 0, [32]byte{})}
c := &Service{cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
p := c.ProtoArrayStore()
require.Equal(t, 0, int(p.FinalizedEpoch()))
}
func TestService_ChainHeads(t *testing.T) {
ctx := context.Background()
c := &Service{cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 100, [32]byte{'a'}, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 101, [32]byte{'b'}, [32]byte{'a'}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 102, [32]byte{'c'}, [32]byte{'b'}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 103, [32]byte{'d'}, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 104, [32]byte{'e'}, [32]byte{'b'}, [32]byte{}, 0, 0))
roots, slots := c.ChainHeads()
require.DeepEqual(t, [][32]byte{{'c'}, {'d'}, {'e'}}, roots)
require.DeepEqual(t, []types.Slot{102, 103, 104}, slots)
}

View File

@@ -6,12 +6,14 @@ import (
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
@@ -20,10 +22,10 @@ import (
// This defines the current chain service's view of head.
type head struct {
slot uint64 // current head slot.
slot types.Slot // current head slot.
root [32]byte // current head root.
block *ethpb.SignedBeaconBlock // current head block.
state *stateTrie.BeaconState // current head state.
state iface.BeaconState // current head state.
}
// Determined the head from the fork choice service and saves its new data
@@ -56,18 +58,18 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
// If the fork choice store is missing justified block info, a node should
// re-initiate fork choice store using the latest justified info.
// This recovers a fatal condition and should not happen in run time.
if !s.forkChoiceStore.HasNode(headStartRoot) {
jb, err := s.beaconDB.Block(ctx, headStartRoot)
if !s.cfg.ForkChoiceStore.HasNode(headStartRoot) {
jb, err := s.cfg.BeaconDB.Block(ctx, headStartRoot)
if err != nil {
return err
}
s.forkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
s.cfg.ForkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block, headStartRoot, f, j); err != nil {
return err
}
}
headRoot, err := s.forkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
headRoot, err := s.cfg.ForkChoiceStore.Head(ctx, j.Epoch, headStartRoot, balances, f.Epoch)
if err != nil {
return err
}
@@ -93,12 +95,12 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// If the head state is not available, just return nil.
// There's nothing to cache
if !s.beaconDB.HasStateSummary(ctx, headRoot) {
if !s.cfg.BeaconDB.HasStateSummary(ctx, headRoot) {
return nil
}
// Get the new head block from DB.
newHeadBlock, err := s.beaconDB.Block(ctx, headRoot)
newHeadBlock, err := s.cfg.BeaconDB.Block(ctx, headRoot)
if err != nil {
return err
}
@@ -107,7 +109,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
}
// Get the new head state from cached state or DB.
newHeadState, err := s.stateGen.StateByRoot(ctx, headRoot)
newHeadState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
if err != nil {
return errors.Wrap(err, "could not retrieve head state in DB")
}
@@ -122,7 +124,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block.Slot),
"oldSlot": fmt.Sprintf("%d", headSlot),
}).Debug("Chain reorg occurred")
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Reorg,
Data: &statefeed.ReorgData{
NewSlot: newHeadBlock.Block.Slot,
@@ -137,7 +139,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
s.setHead(headRoot, newHeadBlock, newHeadState)
// Save the new head root to DB.
if err := s.beaconDB.SaveHeadBlockRoot(ctx, headRoot); err != nil {
if err := s.cfg.BeaconDB.SaveHeadBlockRoot(ctx, headRoot); err != nil {
return errors.Wrap(err, "could not save head root in DB")
}
@@ -147,7 +149,10 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// This gets called to update canonical root mapping. It does not save head block
// root in DB. With the inception of initial-sync-cache-state flag, it uses finalized
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs *stateTrie.BeaconState) error {
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
cachedHeadRoot, err := s.HeadRoot(ctx)
if err != nil {
return errors.Wrap(err, "could not get head root from cache")
@@ -156,16 +161,12 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
return nil
}
if b == nil || b.Block == nil {
return errors.New("cannot save nil head block")
}
s.setHeadInitialSync(r, stateTrie.CopySignedBeaconBlock(b), hs)
s.setHeadInitialSync(r, stateV0.CopySignedBeaconBlock(b), hs)
return nil
}
// This sets head view object which is used to track the head slot, root, block and state.
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
@@ -173,7 +174,7 @@ func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *
s.head = &head{
slot: block.Block.Slot,
root: root,
block: stateTrie.CopySignedBeaconBlock(block),
block: stateV0.CopySignedBeaconBlock(block),
state: state.Copy(),
}
}
@@ -181,7 +182,7 @@ func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state *
// This sets head view object which is used to track the head slot, root, block and state. The method
// assumes that state being passed into the method will not be modified by any other alternate
// caller which holds the state's reference.
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state *stateTrie.BeaconState) {
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
@@ -189,14 +190,14 @@ func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlo
s.head = &head{
slot: block.Block.Slot,
root: root,
block: stateTrie.CopySignedBeaconBlock(block),
block: stateV0.CopySignedBeaconBlock(block),
state: state,
}
}
// This returns the head slot.
// This is a lock free version.
func (s *Service) headSlot() uint64 {
func (s *Service) headSlot() types.Slot {
return s.head.slot
}
@@ -215,13 +216,13 @@ func (s *Service) headRoot() [32]byte {
// It does a full copy on head block for immutability.
// This is a lock free version.
func (s *Service) headBlock() *ethpb.SignedBeaconBlock {
return stateTrie.CopySignedBeaconBlock(s.head.block)
return stateV0.CopySignedBeaconBlock(s.head.block)
}
// This returns the head state.
// It does a full copy on head state for immutability.
// This is a lock free version.
func (s *Service) headState(ctx context.Context) *stateTrie.BeaconState {
func (s *Service) headState(ctx context.Context) iface.BeaconState {
ctx, span := trace.StartSpan(ctx, "blockChain.headState")
defer span.End()
@@ -242,21 +243,21 @@ func (s *Service) hasHeadState() bool {
// This caches justified state balances to be used for fork choice.
func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot [32]byte) error {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
var justifiedState *stateTrie.BeaconState
var justifiedState iface.BeaconState
var err error
if justifiedRoot == s.genesisRoot {
justifiedState, err = s.beaconDB.GenesisState(ctx)
justifiedState, err = s.cfg.BeaconDB.GenesisState(ctx)
if err != nil {
return err
}
} else {
justifiedState, err = s.stateGen.StateByRoot(ctx, justifiedRoot)
justifiedState, err = s.cfg.StateGen.StateByRoot(ctx, justifiedRoot)
if err != nil {
return err
}
@@ -268,7 +269,7 @@ func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot
epoch := helpers.CurrentEpoch(justifiedState)
justifiedBalances := make([]uint64, justifiedState.NumValidators())
if err := justifiedState.ReadFromEveryValidator(func(idx int, val stateTrie.ReadOnlyValidator) error {
if err := justifiedState.ReadFromEveryValidator(func(idx int, val iface.ReadOnlyValidator) error {
if helpers.IsActiveValidatorUsingTrie(val, epoch) {
justifiedBalances[idx] = val.EffectiveBalance()
} else {

View File

@@ -5,6 +5,7 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -22,7 +23,7 @@ func TestSaveHead_Same(t *testing.T) {
service.head = &head{slot: 0, root: r}
require.NoError(t, service.saveHead(context.Background(), r))
assert.Equal(t, uint64(0), service.headSlot(), "Head did not stay the same")
assert.Equal(t, types.Slot(0), service.headSlot(), "Head did not stay the same")
assert.Equal(t, r, service.headRoot(), "Head did not stay the same")
}
@@ -38,23 +39,23 @@ func TestSaveHead_Different(t *testing.T) {
newHeadSignedBlock.Block.Slot = 1
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
assert.Equal(t, types.Slot(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
require.NoError(t, err)
assert.DeepEqual(t, cachedRoot, newRoot[:], "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
}
func TestSaveHead_Different_Reorg(t *testing.T) {
@@ -72,17 +73,17 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
newHeadSignedBlock.Block.ParentRoot = reorgChainParent[:]
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetSlot(1))
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Slot: 1, Root: newRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), headState, newRoot))
require.NoError(t, service.saveHead(context.Background(), newRoot))
assert.Equal(t, uint64(1), service.HeadSlot(), "Head did not change")
assert.Equal(t, types.Slot(1), service.HeadSlot(), "Head did not change")
cachedRoot, err := service.HeadRoot(context.Background())
require.NoError(t, err)
@@ -90,7 +91,7 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
t.Error("Head did not change")
}
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
require.LogsContain(t, hook, "Chain reorg occurred")
}
@@ -100,8 +101,8 @@ func TestCacheJustifiedStateBalances_CanCache(t *testing.T) {
state, _ := testutil.DeterministicGenesisState(t, 100)
r := [32]byte{'a'}
require.NoError(t, service.beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}))
require.NoError(t, service.beaconDB.SaveState(context.Background(), state, r))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: r[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(context.Background(), state, r))
require.NoError(t, service.cacheJustifiedStateBalances(context.Background(), r))
require.DeepEqual(t, service.getJustifiedBalances(), state.Balances(), "Incorrect justified balances")
}
@@ -111,7 +112,7 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
service := setupBeaconChain(t, beaconDB)
b := testutil.NewBeaconBlock()
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)

View File

@@ -45,7 +45,7 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
}
}
nodes := s.forkChoiceStore.Nodes()
nodes := s.cfg.ForkChoiceStore.Nodes()
graph := dot.NewGraph(dot.Directed)
graph.Attr("rankdir", "RL")

View File

@@ -33,10 +33,10 @@ func TestService_TreeHandler(t *testing.T) {
),
StateGen: stategen.New(beaconDB),
}
s, err := New(ctx, cfg)
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))
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, [32]byte{'a'}, [32]byte{'g'}, [32]byte{'c'}, 0, 0))
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 1, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'c'}, 0, 0))
s.setHead([32]byte{'a'}, testutil.NewBeaconBlock(), headState)
rr := httptest.NewRecorder()

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,7 +25,7 @@ func TestReportEpochMetrics_BadAttestation(t *testing.T) {
require.NoError(t, err)
h, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, h.SetCurrentEpochAttestations([]*pb.PendingAttestation{{InclusionDelay: 0}}))
require.NoError(t, h.AppendCurrentEpochAttestations(&pb.PendingAttestation{InclusionDelay: 0}))
err = reportEpochMetrics(context.Background(), s, h)
require.ErrorContains(t, "attestation with inclusion delay of 0", err)
}
@@ -36,7 +36,7 @@ func TestReportEpochMetrics_SlashedValidatorOutOfBound(t *testing.T) {
require.NoError(t, err)
v.Slashed = true
require.NoError(t, h.UpdateValidatorAtIndex(0, v))
require.NoError(t, h.SetCurrentEpochAttestations([]*pb.PendingAttestation{{InclusionDelay: 1, Data: testutil.HydrateAttestationData(&eth.AttestationData{})}}))
require.NoError(t, h.AppendCurrentEpochAttestations(&pb.PendingAttestation{InclusionDelay: 1, Data: testutil.HydrateAttestationData(&eth.AttestationData{})}))
err = reportEpochMetrics(context.Background(), h, h)
require.ErrorContains(t, "slot 0 out of bounds", err)
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -46,7 +46,7 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) error
if err := helpers.ValidateSlotTargetEpoch(a.Data); err != nil {
return err
}
tgt := stateTrie.CopyCheckpoint(a.Data.Target)
tgt := stateV0.CopyCheckpoint(a.Data.Target)
// Note that target root check is ignored here because it was performed in sync's validation pipeline:
// validate_aggregate_proof.go and validate_beacon_attestation.go
@@ -97,7 +97,7 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) error
// We assume trusted attestation in this function has verified signature.
// Update forkchoice store with the new attestation for updating weight.
s.forkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
return nil
}

View File

@@ -6,20 +6,22 @@ import (
"strconv"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/mputil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// getAttPreState retrieves the att pre state by either from the cache or the DB.
func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*stateTrie.BeaconState, error) {
func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (iface.BeaconState, error) {
// Use a multilock to allow scoped holding of a mutex by a checkpoint root + epoch
// allowing us to behave smarter in terms of how this function is used concurrently.
epochKey := strconv.FormatUint(c.Epoch, 10 /* base 10 */)
epochKey := strconv.FormatUint(uint64(c.Epoch), 10 /* base 10 */)
lock := mputil.NewMultilock(string(c.Root) + epochKey)
lock.Lock()
defer lock.Unlock()
@@ -31,7 +33,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
return cachedState, nil
}
baseState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
baseState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for epoch %d", c.Epoch)
}
@@ -41,9 +43,16 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
return nil, err
}
if epochStartSlot > baseState.Slot() {
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
if featureconfig.Get().EnableNextSlotStateCache {
baseState, err = state.ProcessSlotsUsingNextSlotCache(ctx, baseState, c.Root, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
} else {
baseState, err = state.ProcessSlots(ctx, baseState, epochStartSlot)
if err != nil {
return nil, errors.Wrapf(err, "could not process slots up to epoch %d", c.Epoch)
}
}
if err := s.checkpointStateCache.AddCheckpointState(c, baseState); err != nil {
return nil, errors.Wrap(err, "could not saved checkpoint state to cache")
@@ -53,7 +62,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
// To avoid sharing the same state across checkpoint state cache and hot state cache,
// we don't add the state to check point cache.
has, err := s.stateGen.HasStateInCache(ctx, bytesutil.ToBytes32(c.Root))
has, err := s.cfg.StateGen.HasStateInCache(ctx, bytesutil.ToBytes32(c.Root))
if err != nil {
return nil, err
}
@@ -68,9 +77,9 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (*sta
// verifyAttTargetEpoch validates attestation is from the current or previous epoch.
func (s *Service) verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime uint64, c *ethpb.Checkpoint) error {
currentSlot := (nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot
currentSlot := types.Slot((nowTime - genesisTime) / params.BeaconConfig().SecondsPerSlot)
currentEpoch := helpers.SlotToEpoch(currentSlot)
var prevEpoch uint64
var prevEpoch types.Epoch
// Prevents previous epoch under flow
if currentEpoch > 1 {
prevEpoch = currentEpoch - 1
@@ -84,7 +93,7 @@ func (s *Service) verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime u
// verifyBeaconBlock verifies beacon head block is known and not from the future.
func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.AttestationData) error {
r := bytesutil.ToBytes32(data.BeaconBlockRoot)
b, err := s.beaconDB.Block(ctx, r)
b, err := s.cfg.BeaconDB.Block(ctx, r)
if err != nil {
return err
}
@@ -93,8 +102,8 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
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))
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
if b.Block.Slot > data.Slot {
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block.Slot, data.Slot)

View File

@@ -4,7 +4,7 @@ import (
"context"
"testing"
"github.com/gogo/protobuf/proto"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
@@ -29,7 +29,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
_, err = blockTree1(t, beaconDB, []byte{'g'})
@@ -50,7 +50,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(100*params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, BlkWithStateBadAttRoot))
BlkWithValidState := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
@@ -66,7 +66,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, BlkWithValidStateRoot))
tests := []struct {
name string
@@ -135,7 +135,7 @@ func TestStore_OnAttestation_Ok(t *testing.T) {
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisState, pks := testutil.DeterministicGenesisState(t, 64)
require.NoError(t, genesisState.SetGenesisTime(uint64(timeutils.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
@@ -146,8 +146,8 @@ func TestStore_OnAttestation_Ok(t *testing.T) {
copied := genesisState.Copy()
copied, err = state.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.onAttestation(ctx, att[0]))
}
@@ -159,7 +159,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, err := testutil.NewBeaconState()
@@ -175,7 +175,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
err = s.SetBalances([]uint64{0})
require.NoError(t, err)
r := [32]byte{'g'}
require.NoError(t, service.beaconDB.SaveState(ctx, s, r))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, r))
service.justifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
@@ -184,16 +184,16 @@ func TestStore_SaveCheckpointState(t *testing.T) {
r = bytesutil.ToBytes32([]byte{'A'})
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'A'}, 32)}))
s1, err := service.getAttPreState(ctx, cp1)
require.NoError(t, err)
assert.Equal(t, 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot(), "Unexpected state slot")
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, 32)}))
s2, err := service.getAttPreState(ctx, cp2)
require.NoError(t, err)
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
@@ -216,8 +216,8 @@ func TestStore_SaveCheckpointState(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
cp3 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo([]byte{'C'}, 32)}))
s3, err := service.getAttPreState(ctx, cp3)
require.NoError(t, err)
assert.Equal(t, s.Slot(), s3.Slot(), "Unexpected state slot")
@@ -231,24 +231,24 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
epoch := uint64(1)
epoch := types.Epoch(1)
baseState, _ := testutil.DeterministicGenesisState(t, 1)
checkpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("hi"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(checkpoint.Root)))
returned, err := service.getAttPreState(ctx, checkpoint)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), checkpoint.Epoch*params.BeaconConfig().SlotsPerEpoch, "Incorrectly returned base state")
assert.Equal(t, params.BeaconConfig().SlotsPerEpoch.Mul(uint64(checkpoint.Epoch)), returned.Slot(), "Incorrectly returned base state")
cached, err := service.checkpointStateCache.StateByCheckpoint(checkpoint)
require.NoError(t, err)
assert.Equal(t, returned.Slot(), cached.Slot(), "State should have been cached")
epoch = uint64(2)
epoch = 2
newCheckpoint := &ethpb.Checkpoint{Epoch: epoch, Root: bytesutil.PadTo([]byte("bye"), 32)}
require.NoError(t, service.beaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, baseState, bytesutil.ToBytes32(newCheckpoint.Root)))
returned, err = service.getAttPreState(ctx, newCheckpoint)
require.NoError(t, err)
s, err := helpers.StartSlot(newCheckpoint.Epoch)
@@ -259,9 +259,7 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
cached, err = service.checkpointStateCache.StateByCheckpoint(newCheckpoint)
require.NoError(t, err)
if !proto.Equal(returned.InnerStateUnsafe(), cached.InnerStateUnsafe()) {
t.Error("Incorrectly cached base state")
}
require.DeepSSZEqual(t, returned.InnerStateUnsafe(), cached.InnerStateUnsafe())
}
func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
@@ -269,10 +267,10 @@ func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)}))
}
@@ -281,10 +279,10 @@ func TestAttEpoch_MatchCurrentEpoch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Epoch: 1}))
}
@@ -293,10 +291,10 @@ func TestAttEpoch_NotMatch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
nowTime := 2 * params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot
nowTime := 2 * uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
err = service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)})
assert.ErrorContains(t, "target epoch 0 does not match current epoch 2 or prev epoch 1", err)
}
@@ -306,11 +304,11 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
d := testutil.HydrateAttestationData(&ethpb.AttestationData{})
assert.ErrorContains(t, "beacon block 0x000000000000 does not exist", service.verifyBeaconBlock(ctx, d))
assert.ErrorContains(t, "signed beacon block can't be nil", service.verifyBeaconBlock(ctx, d))
}
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
@@ -318,12 +316,12 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
@@ -336,12 +334,12 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.beaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
@@ -354,12 +352,12 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -368,7 +366,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -381,12 +379,12 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -395,7 +393,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -408,7 +406,7 @@ func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
@@ -424,10 +422,10 @@ func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, b32.Block.Slot, r32, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, b33.Block.Slot, r33, r32, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, b32.Block.Slot, r32, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, b33.Block.Slot, r33, r32, [32]byte{}, 0, 0))
_, err = service.forkChoiceStore.Head(ctx, 0, r32, []uint64{}, 0)
_, err = service.cfg.ForkChoiceStore.Head(ctx, 0, r32, []uint64{}, 0)
require.NoError(t, err)
err = service.VerifyFinalizedConsistency(context.Background(), r33[:])
require.NoError(t, err)

View File

@@ -7,9 +7,11 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
@@ -22,8 +24,11 @@ import (
// A custom slot deadline for processing state slots in our cache.
const slotDeadline = 5 * time.Second
// A custom deadline for deposit trie insertion.
const depositDeadline = 20 * time.Second
// This defines size of the upper bound for initial sync block cache.
var initialSyncBlockCacheSize = 2 * params.BeaconConfig().SlotsPerEpoch
var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
// onBlock is called when a gossip block is received. It runs regular state transition on the block.
// The block's signing root should be computed before calling this method to avoid redundant
@@ -126,42 +131,56 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
}
}
// Update finalized check point.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
newFinalized := postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch
if featureconfig.Get().UpdateHeadTimely {
if newFinalized {
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = postState.FinalizedCheckpoint()
}
s.clearInitSyncBlocks()
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
}
// Send notification of the processed block to the state feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: signed.Block.Slot,
BlockRoot: blockRoot,
SignedBlock: signed,
Verified: true,
},
})
}
// Update finalized check point.
if newFinalized {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
fRoot := bytesutil.ToBytes32(postState.FinalizedCheckpoint().Root)
if err := s.forkChoiceStore.Prune(ctx, fRoot); err != nil {
if err := s.cfg.ForkChoiceStore.Prune(ctx, fRoot); err != nil {
return errors.Wrap(err, "could not prune proto array fork choice nodes")
}
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
// Update deposit cache.
finalizedState, err := s.stateGen.StateByRoot(ctx, fRoot)
if err != nil {
return errors.Wrap(err, "could not fetch finalized state")
}
// We update the cache up to the last deposit index in the finalized block's state.
// We can be confident that these deposits will be included in some block
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
s.depositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
if featureconfig.Get().EnablePruningDepositProofs {
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.depositCache.PruneProofs(ctx, eth1DepositIndex); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
if !featureconfig.Get().UpdateHeadTimely {
if err := s.finalizedImpliesNewJustified(ctx, postState); err != nil {
return errors.Wrap(err, "could not save new justified")
}
}
go func() {
// Use a custom deadline here, since this method runs asynchronously.
// We ignore the parent method's context and instead create a new one
// with a custom deadline, therefore using the background context instead.
depCtx, cancel := context.WithTimeout(context.Background(), depositDeadline)
defer cancel()
if err := s.insertFinalizedDeposits(depCtx, fRoot); err != nil {
log.WithError(err).Error("Could not insert finalized deposits.")
}
}()
}
defer reportAttestationInclusion(b)
@@ -169,75 +188,6 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
return s.handleEpochBoundary(ctx, postState)
}
// onBlockInitialSyncStateTransition is called when an initial sync block is received.
// It runs state transition on the block and without fork choice and post operation pool processes.
// The block's signing root should be computed before calling this method to avoid redundant
// computation in this method and methods it calls into.
func (s *Service) onBlockInitialSyncStateTransition(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockInitialSyncStateTransition")
defer span.End()
if signed == nil || signed.Block == nil {
return errors.New("nil block")
}
b := signed.Block
// Retrieve incoming block's pre state.
if err := s.verifyBlkPreState(ctx, b); err != nil {
return err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(signed.Block.ParentRoot))
if err != nil {
return err
}
if preState == nil {
return fmt.Errorf("nil pre state for slot %d", b.Slot)
}
// Exit early if the pre state slot is higher than incoming block's slot.
if preState.Slot() >= signed.Block.Slot {
return nil
}
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
if err != nil {
return errors.Wrap(err, "could not execute state transition")
}
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, true /* init sync */); err != nil {
return err
}
// Save the latest block as head in cache.
if err := s.saveHeadNoDB(ctx, signed, blockRoot, postState); err != nil {
return err
}
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
if uint64(len(s.getInitSyncBlocks())) > initialSyncBlockCacheSize {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
}
if postState.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
if err := s.updateJustifiedInitSync(ctx, postState.CurrentJustifiedCheckpoint()); err != nil {
return err
}
}
// Update finalized check point. Prune the block cache and helper caches on every new finalized epoch.
if postState.FinalizedCheckpointEpoch() > s.finalizedCheckpt.Epoch {
if err := s.updateFinalized(ctx, postState.FinalizedCheckpoint()); err != nil {
return err
}
}
return s.handleEpochBoundary(ctx, postState)
}
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
@@ -255,7 +205,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
if err := s.verifyBlkPreState(ctx, b); err != nil {
return nil, nil, err
}
preState, err := s.stateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
if err != nil {
return nil, nil, err
}
@@ -271,7 +221,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
Messages: [][32]byte{},
}
var set *bls.SignatureSet
boundaries := make(map[[32]byte]*stateTrie.BeaconState)
boundaries := make(map[[32]byte]iface.BeaconState)
for i, b := range blks {
set, preState, err = state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, b)
if err != nil {
@@ -296,14 +246,14 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
return nil, nil, errors.New("batch block signature verification failed")
}
for r, st := range boundaries {
if err := s.stateGen.SaveState(ctx, r, st); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
return nil, nil, err
}
}
// Also saves the last post state which to be used as pre state for the next batch.
lastB := blks[len(blks)-1]
lastBR := blockRoots[len(blockRoots)-1]
if err := s.stateGen.SaveState(ctx, lastBR, preState); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, lastBR, preState); err != nil {
return nil, nil, err
}
if err := s.saveHeadNoDB(ctx, lastB, lastBR, preState); err != nil {
@@ -322,7 +272,7 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, fCheckpoint, jCheckpoint); err != nil {
return err
}
if err := s.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: signed.Block.Slot,
Root: blockRoot[:],
}); err != nil {
@@ -331,7 +281,7 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
// Rate limit how many blocks (2 epochs worth of blocks) a node keeps in the memory.
if uint64(len(s.getInitSyncBlocks())) > initialSyncBlockCacheSize {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
@@ -353,13 +303,18 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb
}
// Epoch boundary bookkeeping such as logging epoch summaries.
func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.BeaconState) error {
func (s *Service) handleEpochBoundary(ctx context.Context, postState iface.BeaconState) error {
if postState.Slot()+1 == s.nextEpochBoundarySlot {
// Update caches for the next epoch at epoch boundary slot - 1.
if err := helpers.UpdateCommitteeCache(postState, helpers.NextEpoch(postState)); err != nil {
return err
}
if err := helpers.UpdateProposerIndicesInCache(postState, helpers.NextEpoch(postState)); err != nil {
copied := postState.Copy()
copied, err := state.ProcessSlots(ctx, copied, copied.Slot()+1)
if err != nil {
return err
}
if err := helpers.UpdateProposerIndicesInCache(copied); err != nil {
return err
}
} else if postState.Slot() >= s.nextEpochBoundarySlot {
@@ -377,7 +332,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.
if err := helpers.UpdateCommitteeCache(postState, helpers.CurrentEpoch(postState)); err != nil {
return err
}
if err := helpers.UpdateProposerIndicesInCache(postState, helpers.CurrentEpoch(postState)); err != nil {
if err := helpers.UpdateProposerIndicesInCache(postState); err != nil {
return err
}
}
@@ -388,7 +343,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState *stateTrie.
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
// to gain information on the most current chain.
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte,
st *stateTrie.BeaconState) error {
st iface.BeaconState) error {
fCheckpoint := st.FinalizedCheckpoint()
jCheckpoint := st.CurrentJustifiedCheckpoint()
if err := s.insertBlockToForkChoiceStore(ctx, blk, root, fCheckpoint, jCheckpoint); err != nil {
@@ -404,7 +359,7 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
if err != nil {
return err
}
s.forkChoiceStore.ProcessAttestation(ctx, indices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
}
return nil
}
@@ -415,7 +370,7 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
return err
}
// Feed in block to fork choice store.
if err := s.forkChoiceStore.ProcessBlock(ctx,
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
@@ -426,15 +381,15 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, st *stateTrie.BeaconState, initSync bool) error {
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
defer span.End()
if initSync {
s.saveInitSyncBlock(r, b)
} else if err := s.beaconDB.SaveBlock(ctx, b); err != nil {
} else if err := s.cfg.BeaconDB.SaveBlock(ctx, b); err != nil {
return errors.Wrapf(err, "could not save block from slot %d", b.Block.Slot)
}
if err := s.stateGen.SaveState(ctx, r, st); err != nil {
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
return errors.Wrap(err, "could not save state")
}
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block, r, st); err != nil {

View File

@@ -6,25 +6,27 @@ import (
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
)
// CurrentSlot returns the current slot based on time.
func (s *Service) CurrentSlot() uint64 {
func (s *Service) CurrentSlot() types.Slot {
return helpers.CurrentSlot(uint64(s.genesisTime.Unix()))
}
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
// to retrieve the state in DB. It verifies the pre state's validity and the incoming block
// is in the correct time window.
func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*stateTrie.BeaconState, error) {
func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
defer span.End()
@@ -33,7 +35,7 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (*
return nil, err
}
preState, err := s.stateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
}
@@ -63,7 +65,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
// Loosen the check to HasBlock because state summary gets saved in batches
// during initial syncing. There's no risk given a state summary object is just a
// a subset of the block object.
if !s.beaconDB.HasStateSummary(ctx, parentRoot) && !s.beaconDB.HasBlock(ctx, parentRoot) {
if !s.cfg.BeaconDB.HasStateSummary(ctx, parentRoot) && !s.cfg.BeaconDB.HasBlock(ctx, parentRoot) {
return errors.New("could not reconstruct parent state")
}
@@ -71,12 +73,12 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
return err
}
has, err := s.stateGen.HasState(ctx, parentRoot)
has, err := s.cfg.StateGen.HasState(ctx, parentRoot)
if err != nil {
return err
}
if !has {
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return errors.Wrap(err, "could not save initial sync blocks")
}
s.clearInitSyncBlocks()
@@ -90,7 +92,7 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
ctx, span := trace.StartSpan(ctx, "blockChain.VerifyBlkDescendant")
defer span.End()
fRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.finalizedCheckpt.Root))
finalizedBlkSigned, err := s.beaconDB.Block(ctx, fRoot)
finalizedBlkSigned, err := s.cfg.BeaconDB.Block(ctx, fRoot)
if err != nil {
return err
}
@@ -143,7 +145,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
if s.hasInitSyncBlock(justifiedRoot) {
newJustifiedBlockSigned = s.getInitSyncBlock(justifiedRoot)
} else {
newJustifiedBlockSigned, err = s.beaconDB.Block(ctx, justifiedRoot)
newJustifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, justifiedRoot)
if err != nil {
return false, err
}
@@ -165,7 +167,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
if s.hasInitSyncBlock(cachedJustifiedRoot) {
justifiedBlockSigned = s.getInitSyncBlock(cachedJustifiedRoot)
} else {
justifiedBlockSigned, err = s.beaconDB.Block(ctx, cachedJustifiedRoot)
justifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, cachedJustifiedRoot)
if err != nil {
return false, err
}
@@ -185,7 +187,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
return true, nil
}
func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconState) error {
func (s *Service) updateJustified(ctx context.Context, state iface.ReadOnlyBeaconState) error {
cpt := state.CurrentJustifiedCheckpoint()
if cpt.Epoch > s.bestJustifiedCheckpt.Epoch {
s.bestJustifiedCheckpt = cpt
@@ -203,7 +205,7 @@ func (s *Service) updateJustified(ctx context.Context, state *stateTrie.BeaconSt
}
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cpt)
return s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cpt)
}
// This caches input checkpoint as justified for the service struct. It rotates current justified to previous justified,
@@ -216,26 +218,27 @@ func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpo
return err
}
return s.beaconDB.SaveJustifiedCheckpoint(ctx, cp)
return s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cp)
}
func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) error {
// Blocks need to be saved so that we can retrieve finalized block from
// DB when migrating states.
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
s.clearInitSyncBlocks()
if err := s.beaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
if err := s.cfg.BeaconDB.SaveFinalizedCheckpoint(ctx, cp); err != nil {
return err
}
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
if !featureconfig.Get().UpdateHeadTimely {
s.prevFinalizedCheckpt = s.finalizedCheckpt
s.finalizedCheckpt = cp
}
fRoot := bytesutil.ToBytes32(cp.Root)
if err := s.stateGen.MigrateToCold(ctx, fRoot); err != nil {
if err := s.cfg.StateGen.MigrateToCold(ctx, fRoot); err != nil {
return errors.Wrap(err, "could not migrate to cold")
}
@@ -254,7 +257,7 @@ func (s *Service) updateFinalized(ctx context.Context, cp *ethpb.Checkpoint) err
// else:
// # root is older than queried slot, thus a skip slot. Return most recent root prior to slot
// return root
func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byte, error) {
func (s *Service) ancestor(ctx context.Context, root []byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestor")
defer span.End()
@@ -275,18 +278,18 @@ func (s *Service) ancestor(ctx context.Context, root []byte, slot uint64) ([]byt
}
// This retrieves an ancestor root using fork choice store. The look up is looping through the a flat array structure.
func (s *Service) ancestorByForkChoiceStore(ctx context.Context, r [32]byte, slot uint64) ([]byte, error) {
func (s *Service) ancestorByForkChoiceStore(ctx context.Context, r [32]byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByForkChoiceStore")
defer span.End()
if !s.forkChoiceStore.HasParent(r) {
if !s.cfg.ForkChoiceStore.HasParent(r) {
return nil, errors.New("could not find root in fork choice store")
}
return s.forkChoiceStore.AncestorRoot(ctx, r, slot)
return s.cfg.ForkChoiceStore.AncestorRoot(ctx, r, slot)
}
// This retrieves an ancestor root using DB. The look up is recursively looking up DB. Slower than `ancestorByForkChoiceStore`.
func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]byte, error) {
func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.ancestorByDB")
defer span.End()
@@ -295,7 +298,7 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]
return nil, ctx.Err()
}
signed, err := s.beaconDB.Block(ctx, r)
signed, err := s.cfg.BeaconDB.Block(ctx, r)
if err != nil {
return nil, errors.Wrap(err, "could not get ancestor block")
}
@@ -330,7 +333,7 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot uint64) ([]
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
// store.justified_checkpoint = state.current_justified_checkpoint
func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *stateTrie.BeaconState) error {
func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state iface.BeaconState) error {
// Update justified if it's different than the one cached in the store.
if !attestationutil.CheckPointIsEqual(s.justifiedCheckpt, state.CurrentJustifiedCheckpoint()) {
if state.CurrentJustifiedCheckpoint().Epoch > s.justifiedCheckpt.Epoch {
@@ -374,8 +377,8 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
}
higherThanFinalized := slot > fSlot
// As long as parent node is not in fork choice store, and parent node is in DB.
for !s.forkChoiceStore.HasNode(parentRoot) && s.beaconDB.HasBlock(ctx, parentRoot) && higherThanFinalized {
b, err := s.beaconDB.Block(ctx, parentRoot)
for !s.cfg.ForkChoiceStore.HasNode(parentRoot) && s.cfg.BeaconDB.HasBlock(ctx, parentRoot) && higherThanFinalized {
b, err := s.cfg.BeaconDB.Block(ctx, parentRoot)
if err != nil {
return err
}
@@ -393,7 +396,7 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
for i := len(pendingNodes) - 1; i >= 0; i-- {
b := pendingNodes[i]
r := pendingRoots[i]
if err := s.forkChoiceStore.ProcessBlock(ctx,
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
@@ -404,15 +407,37 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
return nil
}
// inserts finalized deposits into our finalized deposit trie.
func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.insertFinalizedDeposits")
defer span.End()
// Update deposit cache.
finalizedState, err := s.cfg.StateGen.StateByRoot(ctx, fRoot)
if err != nil {
return errors.Wrap(err, "could not fetch finalized state")
}
// We update the cache up to the last deposit index in the finalized block's state.
// We can be confident that these deposits will be included in some block
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.cfg.DepositCache.PruneProofs(ctx, eth1DepositIndex); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
}
return nil
}
// The deletes input attestations from the attestation pool, so proposers don't include them in a block for the future.
func (s *Service) deletePoolAtts(atts []*ethpb.Attestation) error {
for _, att := range atts {
if helpers.IsAggregated(att) {
if err := s.attPool.DeleteAggregatedAttestation(att); err != nil {
if err := s.cfg.AttPool.DeleteAggregatedAttestation(att); err != nil {
return err
}
} else {
if err := s.attPool.DeleteUnaggregatedAttestation(att); err != nil {
if err := s.cfg.AttPool.DeleteUnaggregatedAttestation(att); err != nil {
return err
}
}

View File

@@ -3,10 +3,13 @@ package blockchain
import (
"context"
"fmt"
"math/big"
"strconv"
"testing"
"time"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
@@ -14,7 +17,8 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/db"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
@@ -35,7 +39,7 @@ func TestStore_OnBlock(t *testing.T) {
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
@@ -44,7 +48,7 @@ func TestStore_OnBlock(t *testing.T) {
require.NoError(t, err)
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
random := testutil.NewBeaconBlock()
@@ -53,16 +57,16 @@ func TestStore_OnBlock(t *testing.T) {
assert.NoError(t, beaconDB.SaveBlock(ctx, random))
randomParentRoot, err := random.Block.HashTreeRoot()
assert.NoError(t, err)
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), randomParentRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), randomParentRoot))
randomParentRoot2 := roots[1]
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2}))
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), bytesutil.ToBytes32(randomParentRoot2)))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot2}))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), bytesutil.ToBytes32(randomParentRoot2)))
tests := []struct {
name string
blk *ethpb.SignedBeaconBlock
s *stateTrie.BeaconState
s iface.BeaconState
time uint64
wantErrString string
}{
@@ -77,7 +81,7 @@ func TestStore_OnBlock(t *testing.T) {
blk: func() *ethpb.SignedBeaconBlock {
b := testutil.NewBeaconBlock()
b.Block.ParentRoot = randomParentRoot2
b.Block.Slot = params.BeaconConfig().FarFutureEpoch
b.Block.Slot = params.BeaconConfig().FarFutureSlot
return b
}(),
s: st.Copy(),
@@ -130,7 +134,7 @@ func TestStore_OnBlockBatch(t *testing.T) {
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
@@ -141,7 +145,7 @@ func TestStore_OnBlockBatch(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
st, keys := testutil.DeterministicGenesisState(t, 64)
@@ -150,9 +154,9 @@ func TestStore_OnBlockBatch(t *testing.T) {
var blks []*ethpb.SignedBeaconBlock
var blkRoots [][32]byte
var firstState *stateTrie.BeaconState
var firstState iface.BeaconState
for i := 1; i < 10; i++ {
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), uint64(i))
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), types.Slot(i))
require.NoError(t, err)
bState, err = state.ExecuteStateTransition(ctx, bState, b)
require.NoError(t, err)
@@ -168,7 +172,7 @@ func TestStore_OnBlockBatch(t *testing.T) {
blks[0].Block.ParentRoot = gRoot[:]
require.NoError(t, beaconDB.SaveBlock(context.Background(), blks[0]))
require.NoError(t, service.stateGen.SaveState(ctx, blkRoots[0], firstState))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, blkRoots[0], firstState))
_, _, err = service.onBlockBatch(ctx, blks[1:], blkRoots[1:])
require.NoError(t, err)
}
@@ -180,7 +184,7 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.genesisTime = time.Now()
@@ -196,10 +200,10 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.beaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}
update, err = service.shouldUpdateCurrentJustified(ctx, &ethpb.Checkpoint{Root: newJustifiedRoot[:]})
@@ -214,7 +218,7 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
lastJustifiedBlk := testutil.NewBeaconBlock()
lastJustifiedBlk.Block.ParentRoot = bytesutil.PadTo([]byte{'G'}, 32)
@@ -224,10 +228,10 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.beaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}
@@ -244,10 +248,10 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
genesisStateRoot := [32]byte{}
@@ -258,14 +262,14 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
b.Block.ParentRoot = gRoot[:]
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
}
@@ -277,7 +281,7 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
genesisStateRoot := [32]byte{}
@@ -288,7 +292,7 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
b := testutil.NewBeaconBlock()
@@ -299,10 +303,10 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
assert.ErrorContains(t, wanted, err)
b.Block.ParentRoot = gRoot[:]
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{Slot: 1})
s, err := stateV0.InitializeFromProto(&pb.BeaconState{Slot: 1})
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.stateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
}
@@ -311,7 +315,7 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
signedBlock := testutil.NewBeaconBlock()
@@ -336,7 +340,7 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
service.bestJustifiedCheckpt.Epoch = 2
require.NoError(t, service.updateJustified(context.Background(), s))
assert.Equal(t, uint64(2), service.bestJustifiedCheckpt.Epoch, "Incorrect justified epoch in service")
assert.Equal(t, types.Epoch(2), service.bestJustifiedCheckpt.Epoch, "Incorrect justified epoch in service")
}
func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
@@ -344,9 +348,9 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
genesisStateRoot := [32]byte{}
@@ -357,7 +361,7 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
@@ -371,10 +375,10 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
assert.Equal(t, 5, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[4])), "Didn't save node")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[6])), "Didn't save node")
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[8])), "Didn't save node")
assert.Equal(t, 5, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[4])), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[6])), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(roots[8])), "Didn't save node")
}
func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
@@ -382,9 +386,9 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
genesisStateRoot := [32]byte{}
@@ -395,7 +399,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
roots, err := blockTree1(t, beaconDB, validGenesisRoot[:])
require.NoError(t, err)
@@ -409,12 +413,12 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
assert.Equal(t, 5, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, 5, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
// Ensure all roots and their respective blocks exist.
wantedRoots := [][]byte{roots[0], roots[3], roots[4], roots[6], roots[8]}
for i, rt := range wantedRoots {
assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(rt)), fmt.Sprintf("Didn't save node: %d", i))
assert.Equal(t, true, service.beaconDB.HasBlock(context.Background(), bytesutil.ToBytes32(rt)))
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(bytesutil.ToBytes32(rt)), fmt.Sprintf("Didn't save node: %d", i))
assert.Equal(t, true, service.cfg.BeaconDB.HasBlock(context.Background(), bytesutil.ToBytes32(rt)))
}
}
@@ -423,9 +427,9 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
// Set finalized epoch to 1.
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1}
@@ -437,24 +441,24 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st.Copy(), validGenesisRoot))
// Define a tree branch, slot 63 <- 64 <- 65
b63 := testutil.NewBeaconBlock()
b63.Block.Slot = 63
require.NoError(t, service.beaconDB.SaveBlock(ctx, b63))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b63))
r63, err := b63.Block.HashTreeRoot()
require.NoError(t, err)
b64 := testutil.NewBeaconBlock()
b64.Block.Slot = 64
b64.Block.ParentRoot = r63[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b64))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b64))
r64, err := b64.Block.HashTreeRoot()
require.NoError(t, err)
b65 := testutil.NewBeaconBlock()
b65.Block.Slot = 65
b65.Block.ParentRoot = r64[:]
require.NoError(t, service.beaconDB.SaveBlock(ctx, b65))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b65))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
err = service.fillInForkChoiceMissingBlocks(
@@ -462,10 +466,10 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
require.NoError(t, err)
// There should be 2 nodes, block 65 and block 64.
assert.Equal(t, 2, len(service.forkChoiceStore.Nodes()), "Miss match nodes")
assert.Equal(t, 2, len(service.cfg.ForkChoiceStore.Nodes()), "Miss match nodes")
// Block with slot 63 should be in fork choice because it's less than finalized epoch 1.
assert.Equal(t, true, service.forkChoiceStore.HasNode(r63), "Didn't save node")
assert.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r63), "Didn't save node")
}
// blockTree1 constructs the following tree:
@@ -561,11 +565,11 @@ func TestCurrentSlot_HandlesOverflow(t *testing.T) {
svc := Service{genesisTime: timeutils.Now().Add(1 * time.Hour)}
slot := svc.CurrentSlot()
require.Equal(t, uint64(0), slot, "Unexpected slot")
require.Equal(t, types.Slot(0), slot, "Unexpected slot")
}
func TestAncestorByDB_CtxErr(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
service, err := New(ctx, &Config{})
service, err := NewService(ctx, &Config{})
require.NoError(t, err)
cancel()
@@ -578,7 +582,7 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b1 := testutil.NewBeaconBlock()
@@ -621,7 +625,7 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
func TestAncestor_CanUseForkchoice(t *testing.T) {
ctx := context.Background()
cfg := &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b1 := testutil.NewBeaconBlock()
@@ -645,7 +649,7 @@ func TestAncestor_CanUseForkchoice(t *testing.T) {
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), b.Block.Slot, r, bytesutil.ToBytes32(b.Block.ParentRoot), [32]byte{}, 0, 0)) // Saves blocks to fork choice store.
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), b.Block.Slot, r, bytesutil.ToBytes32(b.Block.ParentRoot), [32]byte{}, 0, 0)) // Saves blocks to fork choice store.
}
r, err := service.ancestor(context.Background(), r200[:], 150)
@@ -660,7 +664,7 @@ func TestAncestor_CanUseDB(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b1 := testutil.NewBeaconBlock()
@@ -685,7 +689,7 @@ func TestAncestor_CanUseDB(t *testing.T) {
require.NoError(t, beaconDB.SaveBlock(context.Background(), beaconBlock)) // Saves blocks to DB.
}
require.NoError(t, service.forkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
r, err := service.ancestor(context.Background(), r200[:], 150)
require.NoError(t, err)
@@ -697,7 +701,7 @@ func TestAncestor_CanUseDB(t *testing.T) {
func TestEnsureRootNotZeroHashes(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
service.genesisRoot = [32]byte{'a'}
@@ -751,13 +755,13 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
beaconState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(test.args.stateCheckPoint))
service, err := New(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
require.NoError(t, err)
service.justifiedCheckpt = test.args.cachedCheckPoint
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo(test.want.Root, 32)}))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: bytesutil.PadTo(test.want.Root, 32)}))
genesisState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, genesisState, bytesutil.ToBytes32(test.want.Root)))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, genesisState, bytesutil.ToBytes32(test.want.Root)))
if test.args.diffFinalizedCheckPoint {
b1 := testutil.NewBeaconBlock()
@@ -774,7 +778,7 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, service.beaconDB.SaveBlock(context.Background(), beaconBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), beaconBlock))
}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: []byte{'c'}, Epoch: 1}
service.justifiedCheckpt.Root = r100[:]
@@ -843,7 +847,7 @@ func TestVerifyBlkDescendant(t *testing.T) {
},
}
for _, tt := range tests {
service, err := New(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: tt.args.finalizedRoot[:],
@@ -861,17 +865,17 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
cfg := &Config{BeaconDB: beaconDB}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gBlk := testutil.NewBeaconBlock()
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveBlock(ctx, gBlk))
require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, gBlk))
require.NoError(t, service.cfg.BeaconDB.SaveGenesisBlockRoot(ctx, gRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.beaconDB.SaveState(ctx, beaconState, gRoot))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, beaconState, gRoot))
service.genesisRoot = gRoot
currentCp := &ethpb.Checkpoint{Epoch: 1}
service.justifiedCheckpt = currentCp
@@ -879,30 +883,31 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
require.NoError(t, service.updateJustifiedInitSync(ctx, newCp))
assert.DeepEqual(t, currentCp, service.prevJustifiedCheckpt, "Incorrect previous justified checkpoint")
assert.DeepEqual(t, newCp, service.CurrentJustifiedCheckpt(), "Incorrect current justified checkpoint in cache")
cp, err := service.beaconDB.JustifiedCheckpoint(ctx)
assert.DeepSSZEqual(t, currentCp, service.prevJustifiedCheckpt, "Incorrect previous justified checkpoint")
assert.DeepSSZEqual(t, newCp, service.CurrentJustifiedCheckpt(), "Incorrect current justified checkpoint in cache")
cp, err := service.cfg.BeaconDB.JustifiedCheckpoint(ctx)
require.NoError(t, err)
assert.DeepEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
assert.DeepSSZEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
}
func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(1))
service.head = &head{}
service.head = &head{state: (*stateV0.BeaconState)(nil)}
require.ErrorContains(t, "failed to initialize precompute: nil inner state", service.handleEpochBoundary(ctx, s))
}
func TestHandleEpochBoundary_UpdateFirstSlot(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
s, _ := testutil.DeterministicGenesisState(t, 1024)
@@ -923,27 +928,70 @@ func TestOnBlock_CanFinalize(t *testing.T) {
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
DepositCache: depositCache,
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gs, keys := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.beaconDB.GenesisBlock(ctx)
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
testState := gs.Copy()
for i := uint64(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
blk, err := testutil.GenerateFullBlock(testState, keys, testutil.DefaultBlockGenConfig(), i)
require.NoError(t, err)
r, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.onBlock(ctx, blk, r))
testState, err = service.stateGen.StateByRoot(ctx, r)
testState, err = service.cfg.StateGen.StateByRoot(ctx, r)
require.NoError(t, err)
}
require.Equal(t, uint64(3), service.CurrentJustifiedCheckpt().Epoch)
require.Equal(t, uint64(2), service.FinalizedCheckpt().Epoch)
require.Equal(t, types.Epoch(3), service.CurrentJustifiedCheckpt().Epoch)
require.Equal(t, types.Epoch(2), service.FinalizedCheckpt().Epoch)
}
func TestInsertFinalizedDeposits(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
DepositCache: depositCache,
}
service, err := NewService(ctx, cfg)
require.NoError(t, err)
gs, _ := testutil.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
gs = gs.Copy()
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 10}))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
zeroSig := [96]byte{}
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
root := []byte(strconv.Itoa(int(i)))
depositCache.InsertDeposit(ctx, &ethpb.Deposit{Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.FromBytes48([48]byte{}),
WithdrawalCredentials: params.BeaconConfig().ZeroHash[:],
Amount: 0,
Signature: zeroSig[:],
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root))
}
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
fDeposits := depositCache.FinalizedDeposits(ctx)
assert.Equal(t, 9, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps := depositCache.AllDeposits(ctx, big.NewInt(109))
for _, d := range deps {
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
}
}

View File

@@ -10,7 +10,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
@@ -21,7 +21,7 @@ import (
// AttestationReceiver interface defines the methods of chain service receive and processing new attestations.
type AttestationReceiver interface {
ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error
AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error)
AttestationPreState(ctx context.Context, att *ethpb.Attestation) (iface.BeaconState, error)
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
VerifyFinalizedConsistency(ctx context.Context, root []byte) error
}
@@ -39,16 +39,11 @@ func (s *Service) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Att
return errors.Wrap(err, "could not process attestation")
}
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
return nil
}
return nil
}
// AttestationPreState returns the pre state of attestation.
func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (*state.BeaconState, error) {
func (s *Service) AttestationPreState(ctx context.Context, att *ethpb.Attestation) (iface.BeaconState, error) {
ss, err := helpers.StartSlot(att.Data.Target.Epoch)
if err != nil {
return nil, err
@@ -81,7 +76,7 @@ func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestat
func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) error {
// A canonical root implies the root to has an ancestor that aligns with finalized check point.
// In this case, we could exit early to save on additional computation.
if s.forkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
if s.cfg.ForkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
return nil
}
@@ -102,10 +97,10 @@ func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) e
}
// This routine processes fork choice attestations from the pool to account for validator votes and fork choice.
func (s *Service) processAttestationsRoutine(subscribedToStateEvents chan struct{}) {
func (s *Service) processAttestationsRoutine(subscribedToStateEvents chan<- struct{}) {
// Wait for state to be initialized.
stateChannel := make(chan *feed.Event, 1)
stateSub := s.stateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
subscribedToStateEvents <- struct{}{}
<-stateChannel
stateSub.Unsubscribe()
@@ -124,14 +119,22 @@ func (s *Service) processAttestationsRoutine(subscribedToStateEvents chan struct
case <-s.ctx.Done():
return
case <-st.C():
// Continue when there's no fork choice attestation, there's nothing to process and update head.
// This covers the condition when the node is still initial syncing to the head of the chain.
if s.cfg.AttPool.ForkchoiceAttestationCount() == 0 {
continue
}
s.processAttestations(s.ctx)
if err := s.updateHead(s.ctx, s.getJustifiedBalances()); err != nil {
log.Warnf("Resolving fork due to new attestation: %v", err)
}
}
}
}
// This processes fork choice attestations from the pool to account for validator votes and fork choice.
func (s *Service) processAttestations(ctx context.Context) {
atts := s.attPool.ForkchoiceAttestations()
atts := s.cfg.AttPool.ForkchoiceAttestations()
for _, a := range atts {
// Based on the spec, don't process the attestation until the subsequent slot.
// This delays consideration in the fork choice until their slot is in the past.
@@ -141,13 +144,13 @@ func (s *Service) processAttestations(ctx context.Context) {
continue
}
hasState := s.beaconDB.HasStateSummary(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
hasState := s.cfg.BeaconDB.HasStateSummary(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
hasBlock := s.hasBlock(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
if !(hasState && hasBlock) {
continue
}
if err := s.attPool.DeleteForkchoiceAttestation(a); err != nil {
if err := s.cfg.AttPool.DeleteForkchoiceAttestation(a); err != nil {
log.WithError(err).Error("Could not delete fork choice attestation in pool")
}

View File

@@ -5,6 +5,7 @@ import (
"testing"
"time"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
@@ -27,7 +28,7 @@ func TestAttestationCheckPtState_FarFutureSlot(t *testing.T) {
chainService := setupBeaconChain(t, beaconDB)
chainService.genesisTime = time.Now()
e := helpers.MaxSlotBuffer/params.BeaconConfig().SlotsPerEpoch + 1
e := types.Epoch(helpers.MaxSlotBuffer/uint64(params.BeaconConfig().SlotsPerEpoch) + 1)
_, err := chainService.AttestationPreState(context.Background(), &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: e}}})
require.ErrorContains(t, "exceeds max allowed value relative to the local clock", err)
}
@@ -37,18 +38,18 @@ func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, 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))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -65,18 +66,18 @@ func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
require.NoError(t, err)
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.beaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, 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))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -99,7 +100,7 @@ func TestProcessAttestations_Ok(t *testing.T) {
StateGen: stategen.New(beaconDB),
AttPool: attestations.NewPool(),
}
service, err := New(ctx, cfg)
service, err := NewService(ctx, cfg)
service.genesisTime = timeutils.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
require.NoError(t, err)
genesisState, pks := testutil.DeterministicGenesisState(t, 64)
@@ -111,10 +112,10 @@ func TestProcessAttestations_Ok(t *testing.T) {
copied := genesisState.Copy()
copied, err = state.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.beaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.forkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.attPool.SaveForkchoiceAttestations(atts))
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, tRoot, tRoot, tRoot, 1, 1))
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(atts))
service.processAttestations(ctx)
require.Equal(t, 0, len(service.attPool.ForkchoiceAttestations()))
require.Equal(t, 0, len(service.cfg.AttPool.ForkchoiceAttestations()))
require.LogsDoNotContain(t, hook, "Could not process attestation for fork choice")
}

View File

@@ -4,23 +4,24 @@ import (
"context"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// This defines how many epochs since finality the run time will begin to save hot state on to the DB.
var epochsSinceFinalitySaveHotStateDB = 100
var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
// BlockReceiver interface defines the methods of chain service receive and processing new blocks.
type BlockReceiver interface {
ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error
HasInitSyncBlock(root [32]byte) bool
}
@@ -33,7 +34,8 @@ type BlockReceiver interface {
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)
receivedTime := timeutils.Now()
blockCopy := stateV0.CopySignedBeaconBlock(block)
// Apply state transition on the new block.
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
@@ -43,21 +45,22 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
}
// Update and save head block after fork choice.
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
if !featureconfig.Get().UpdateHeadTimely {
if err := s.updateHead(ctx, s.getJustifiedBalances()); err != nil {
log.WithError(err).Warn("Could not update head")
}
// Send notification of the processed block to the state feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
SignedBlock: blockCopy,
Verified: true,
},
})
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
SignedBlock: blockCopy,
Verified: true,
},
})
// Handle post block operations such as attestations and exits.
if err := s.handlePostBlockOperations(blockCopy.Block); err != nil {
return err
@@ -72,48 +75,11 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
// Log block sync status.
logBlockSyncStatus(blockCopy.Block, blockRoot, s.finalizedCheckpt)
// Log state transition data.
logStateTransitionData(blockCopy.Block)
return nil
}
// ReceiveBlockInitialSync processes the input block for the purpose of initial syncing.
// This method should only be used on blocks during initial syncing phase.
func (s *Service) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockNoVerify")
defer span.End()
blockCopy := stateTrie.CopySignedBeaconBlock(block)
// Apply state transition on the new block.
if err := s.onBlockInitialSyncStateTransition(ctx, blockCopy, blockRoot); err != nil {
err := errors.Wrap(err, "could not process block")
traceutil.AnnotateError(span, err)
if err := logBlockSyncStatus(blockCopy.Block, blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
return err
}
// Send notification of the processed block to the state feed.
s.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
BlockRoot: blockRoot,
SignedBlock: blockCopy,
Verified: true,
},
})
// Reports on blockCopy and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
// Log state transition data.
log.WithFields(logrus.Fields{
"slot": blockCopy.Block.Slot,
"attestations": len(blockCopy.Block.Body.Attestations),
"deposits": len(blockCopy.Block.Body.Deposits),
}).Debug("Finished applying state transition")
logStateTransitionData(blockCopy.Block)
return nil
}
@@ -134,13 +100,13 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
}
for i, b := range blocks {
blockCopy := stateTrie.CopySignedBeaconBlock(b)
blockCopy := stateV0.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{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
@@ -176,18 +142,18 @@ func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
}
// Add block attestations to the fork choice pool to compute head.
if err := s.attPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
log.Errorf("Could not save block attestations for fork choice: %v", err)
return nil
}
// Mark block exits as seen so we don't include same ones in future blocks.
for _, e := range b.Body.VoluntaryExits {
s.exitPool.MarkIncluded(e)
s.cfg.ExitPool.MarkIncluded(e)
}
// Mark attester slashings as seen so we don't include same ones in future blocks.
for _, as := range b.Body.AttesterSlashings {
s.slashingPool.MarkIncludedAttesterSlashing(as)
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
}
return nil
}
@@ -197,15 +163,15 @@ func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
func (s *Service) checkSaveHotStateDB(ctx context.Context) error {
currentEpoch := helpers.SlotToEpoch(s.CurrentSlot())
// Prevent `sinceFinality` going underflow.
var sinceFinality uint64
var sinceFinality types.Epoch
if currentEpoch > s.finalizedCheckpt.Epoch {
sinceFinality = currentEpoch - s.finalizedCheckpt.Epoch
}
if sinceFinality >= uint64(epochsSinceFinalitySaveHotStateDB) {
s.stateGen.EnableSaveHotStateToDB(ctx)
if sinceFinality >= epochsSinceFinalitySaveHotStateDB {
s.cfg.StateGen.EnableSaveHotStateToDB(ctx)
return nil
}
return s.stateGen.DisableSaveHotStateToDB(ctx)
return s.cfg.StateGen.DisableSaveHotStateToDB(ctx)
}

View File

@@ -6,6 +6,7 @@ import (
"testing"
"time"
types "github.com/prysmaticlabs/eth2-types"
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"
@@ -25,7 +26,7 @@ func TestService_ReceiveBlock(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot types.Slot) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
@@ -72,7 +73,7 @@ func TestService_ReceiveBlock(t *testing.T) {
),
},
check: func(t *testing.T, s *Service) {
if baCount := len(s.attPool.BlockAttestations()); baCount != 2 {
if baCount := len(s.cfg.AttPool.BlockAttestations()); baCount != 2 {
t.Errorf("Did not get the correct number of block attestations saved to the pool. "+
"Got %d but wanted %d", baCount, 2)
}
@@ -92,7 +93,7 @@ func TestService_ReceiveBlock(t *testing.T) {
),
},
check: func(t *testing.T, s *Service) {
pending := s.exitPool.PendingExits(genesis, 1, true /* no limit */)
pending := s.cfg.ExitPool.PendingExits(genesis, 1, true /* no limit */)
if len(pending) != 0 {
t.Errorf(
"Did not mark the correct number of exits. Got %d pending but wanted %d",
@@ -108,7 +109,7 @@ func TestService_ReceiveBlock(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
@@ -133,10 +134,10 @@ func TestService_ReceiveBlock(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := New(ctx, cfg)
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
@@ -174,10 +175,10 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := New(ctx, cfg)
s, err := NewService(ctx, cfg)
require.NoError(t, err)
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
@@ -191,99 +192,18 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
wg.Done()
}()
wg.Wait()
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
// Verify fork choice has processed the block. (Genesis block and the new block)
assert.Equal(t, 2, len(s.forkChoiceStore.Nodes()))
}
func TestService_ReceiveBlockInitialSync(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
}
type args struct {
block *ethpb.SignedBeaconBlock
}
tests := []struct {
name string
args args
wantedErr string
check func(*testing.T, *Service)
}{
{
name: "applies block with state transition",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
},
},
{
name: "notifies block processed on state feed",
args: args{
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
beaconDB := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
cfg := &Config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
0, // finalizedEpoch
genesisBlockRoot,
),
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := New(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlockInitialSync(ctx, tt.args.block, root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
tt.check(t, s)
}
})
}
assert.Equal(t, 2, len(s.cfg.ForkChoiceStore.Nodes()))
}
func TestService_ReceiveBlockBatch(t *testing.T) {
ctx := context.Background()
genesis, keys := testutil.DeterministicGenesisState(t, 64)
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot uint64) *ethpb.SignedBeaconBlock {
genFullBlock := func(t *testing.T, conf *testutil.BlockGenConfig, slot types.Slot) *ethpb.SignedBeaconBlock {
blk, err := testutil.GenerateFullBlock(genesis, keys, conf, slot)
assert.NoError(t, err)
return blk
@@ -304,8 +224,8 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 2 /*slot*/),
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, uint64(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, uint64(2), s.head.block.Block.Slot, "Incorrect head block slot")
assert.Equal(t, types.Slot(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, types.Slot(2), s.head.block.Block.Slot, "Incorrect head block slot")
},
},
{
@@ -314,7 +234,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
block: genFullBlock(t, testutil.DefaultBlockGenConfig(), 1 /*slot*/),
},
check: func(t *testing.T, s *Service) {
if recvd := len(s.stateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
if recvd := len(s.cfg.StateNotifier.(*blockchainTesting.MockStateNotifier).ReceivedEvents()); recvd < 1 {
t.Errorf("Received %d state notifications, expected at least 1", recvd)
}
},
@@ -336,11 +256,11 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := New(ctx, cfg)
s, err := NewService(ctx, cfg)
require.NoError(t, err)
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.beaconDB.GenesisBlock(ctx)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
@@ -362,7 +282,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
}
func TestService_HasInitSyncBlock(t *testing.T) {
s, err := New(context.Background(), &Config{StateNotifier: &blockchainTesting.MockStateNotifier{}})
s, err := NewService(context.Background(), &Config{StateNotifier: &blockchainTesting.MockStateNotifier{}})
require.NoError(t, err)
r := [32]byte{'a'}
if s.HasInitSyncBlock(r) {
@@ -377,9 +297,9 @@ func TestService_HasInitSyncBlock(t *testing.T) {
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := New(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
st := params.BeaconConfig().SlotsPerEpoch * uint64(epochsSinceFinalitySaveHotStateDB)
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
s.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
s.finalizedCheckpt = &ethpb.Checkpoint{}
@@ -390,7 +310,7 @@ func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := New(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
@@ -403,7 +323,7 @@ func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := New(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 10000000}
s.genesisTime = time.Now()

View File

@@ -11,16 +11,15 @@ import (
"time"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
f "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
@@ -28,9 +27,10 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
@@ -45,85 +45,58 @@ const headSyncMinEpochsAfterCheckpoint = 128
// Service represents a service that handles the internal
// logic of managing the full PoS beacon chain.
type Service struct {
cfg *Config
ctx context.Context
cancel context.CancelFunc
beaconDB db.HeadAccessDatabase
depositCache *depositcache.DepositCache
chainStartFetcher powchain.ChainStartFetcher
attPool attestations.Pool
slashingPool *slashings.Pool
exitPool *voluntaryexits.Pool
genesisTime time.Time
p2p p2p.Broadcaster
maxRoutines int
head *head
headLock sync.RWMutex
stateNotifier statefeed.Notifier
genesisRoot [32]byte
forkChoiceStore f.ForkChoicer
justifiedCheckpt *ethpb.Checkpoint
prevJustifiedCheckpt *ethpb.Checkpoint
bestJustifiedCheckpt *ethpb.Checkpoint
finalizedCheckpt *ethpb.Checkpoint
prevFinalizedCheckpt *ethpb.Checkpoint
nextEpochBoundarySlot uint64
nextEpochBoundarySlot types.Slot
boundaryRoots [][32]byte
checkpointStateCache *cache.CheckpointStateCache
stateGen *stategen.State
opsService *attestations.Service
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
initSyncBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
wsEpoch uint64
wsRoot []byte
wsVerified bool
}
// Config options for the service.
type Config struct {
BeaconBlockBuf int
ChainStartFetcher powchain.ChainStartFetcher
BeaconDB db.HeadAccessDatabase
DepositCache *depositcache.DepositCache
AttPool attestations.Pool
ExitPool *voluntaryexits.Pool
SlashingPool *slashings.Pool
P2p p2p.Broadcaster
MaxRoutines int
StateNotifier statefeed.Notifier
ForkChoiceStore f.ForkChoicer
OpsService *attestations.Service
StateGen *stategen.State
WspBlockRoot []byte
WspEpoch uint64
BeaconBlockBuf int
ChainStartFetcher powchain.ChainStartFetcher
BeaconDB db.HeadAccessDatabase
DepositCache *depositcache.DepositCache
AttPool attestations.Pool
ExitPool voluntaryexits.PoolManager
SlashingPool slashings.PoolManager
P2p p2p.Broadcaster
MaxRoutines int
StateNotifier statefeed.Notifier
ForkChoiceStore f.ForkChoicer
OpsService *attestations.Service
StateGen *stategen.State
WeakSubjectivityCheckpt *ethpb.Checkpoint
}
// New instantiates a new block service instance that will
// NewService instantiates a new block service instance that will
// be registered into a running beacon node.
func New(ctx context.Context, cfg *Config) (*Service, error) {
func NewService(ctx context.Context, cfg *Config) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
return &Service{
cfg: cfg,
ctx: ctx,
cancel: cancel,
beaconDB: cfg.BeaconDB,
depositCache: cfg.DepositCache,
chainStartFetcher: cfg.ChainStartFetcher,
attPool: cfg.AttPool,
exitPool: cfg.ExitPool,
slashingPool: cfg.SlashingPool,
p2p: cfg.P2p,
maxRoutines: cfg.MaxRoutines,
stateNotifier: cfg.StateNotifier,
forkChoiceStore: cfg.ForkChoiceStore,
boundaryRoots: [][32]byte{},
checkpointStateCache: cache.NewCheckpointStateCache(),
opsService: cfg.OpsService,
stateGen: cfg.StateGen,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
justifiedBalances: make([]uint64, 0),
wsEpoch: cfg.WspEpoch,
wsRoot: cfg.WspBlockRoot,
}, nil
}
@@ -132,7 +105,7 @@ func (s *Service) Start() {
// For running initial sync with state cache, in an event of restart, we use
// last finalized check point as start point to sync instead of head
// state. This is because we no longer save state every slot during sync.
cp, err := s.beaconDB.FinalizedCheckpoint(s.ctx)
cp, err := s.cfg.BeaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
@@ -142,7 +115,7 @@ func (s *Service) Start() {
// the finalized root is defined as zero hashes instead of genesis root hash.
// We want to use genesis root to retrieve for state.
if r == params.BeaconConfig().ZeroHash {
genesisBlock, err := s.beaconDB.GenesisBlock(s.ctx)
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
@@ -153,7 +126,7 @@ func (s *Service) Start() {
}
}
}
beaconState, err := s.stateGen.StateByRoot(s.ctx, r)
beaconState, err := s.cfg.StateGen.StateByRoot(s.ctx, r)
if err != nil {
log.Fatalf("Could not fetch beacon state by root: %v", err)
}
@@ -165,13 +138,13 @@ func (s *Service) Start() {
if beaconState != nil {
log.Info("Blockchain data already exists in DB, initializing...")
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
s.opsService.SetGenesisTime(beaconState.GenesisTime())
s.cfg.OpsService.SetGenesisTime(beaconState.GenesisTime())
if err := s.initializeChainInfo(s.ctx); err != nil {
log.Fatalf("Could not set up chain info: %v", err)
}
// We start a counter to genesis, if needed.
gState, err := s.beaconDB.GenesisState(s.ctx)
gState, err := s.cfg.BeaconDB.GenesisState(s.ctx)
if err != nil {
log.Fatalf("Could not retrieve genesis state: %v", err)
}
@@ -181,24 +154,24 @@ func (s *Service) Start() {
}
go slotutil.CountdownToGenesis(s.ctx, s.genesisTime, uint64(gState.NumValidators()), gRoot)
justifiedCheckpoint, err := s.beaconDB.JustifiedCheckpoint(s.ctx)
justifiedCheckpoint, err := s.cfg.BeaconDB.JustifiedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get justified checkpoint: %v", err)
}
finalizedCheckpoint, err := s.beaconDB.FinalizedCheckpoint(s.ctx)
finalizedCheckpoint, err := s.cfg.BeaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not get finalized checkpoint: %v", err)
}
// Resume fork choice.
s.justifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.justifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
if err := s.cacheJustifiedStateBalances(s.ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))); err != nil {
log.Fatalf("Could not cache justified state balances: %v", err)
}
s.prevJustifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = stateTrie.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = stateTrie.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = stateTrie.CopyCheckpoint(finalizedCheckpoint)
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
s.resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint)
ss, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
@@ -221,7 +194,7 @@ func (s *Service) Start() {
log.Fatalf("Could not verify weak subjectivity checkpoint: %v", err)
}
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Initialized,
Data: &statefeed.InitializedData{
StartTime: s.genesisTime,
@@ -230,13 +203,13 @@ func (s *Service) Start() {
})
} else {
log.Info("Waiting to reach the validator deposit threshold to start the beacon chain...")
if s.chainStartFetcher == nil {
if s.cfg.ChainStartFetcher == nil {
log.Fatal("Not configured web3Service for POW chain")
return // return need for TestStartUninitializedChainWithoutConfigPOWChain.
}
go func() {
stateChannel := make(chan *feed.Event, 1)
stateSub := s.stateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
<-attestationProcessorSubscribed
for {
@@ -269,8 +242,8 @@ func (s *Service) Start() {
// processChainStartTime initializes a series of deposits from the ChainStart deposits in the eth1
// deposit contract, initializes the beacon chain's state, and kicks off the beacon chain.
func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Time) {
preGenesisState := s.chainStartFetcher.PreGenesisState()
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState, s.chainStartFetcher.ChainStartEth1Data())
preGenesisState := s.cfg.ChainStartFetcher.PreGenesisState()
initializedState, err := s.initializeBeaconChain(ctx, genesisTime, preGenesisState, s.cfg.ChainStartFetcher.ChainStartEth1Data())
if err != nil {
log.Fatalf("Could not initialize beacon chain: %v", err)
}
@@ -283,7 +256,7 @@ func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Ti
// We send out a state initialized event to the rest of the services
// running in the beacon node.
s.stateNotifier.StateFeed().Send(&feed.Event{
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Initialized,
Data: &statefeed.InitializedData{
StartTime: genesisTime,
@@ -298,8 +271,8 @@ func (s *Service) processChainStartTime(ctx context.Context, genesisTime time.Ti
func (s *Service) initializeBeaconChain(
ctx context.Context,
genesisTime time.Time,
preGenesisState *stateTrie.BeaconState,
eth1data *ethpb.Eth1Data) (*stateTrie.BeaconState, error) {
preGenesisState iface.BeaconState,
eth1data *ethpb.Eth1Data) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "beacon-chain.Service.initializeBeaconChain")
defer span.End()
s.genesisTime = genesisTime
@@ -317,17 +290,17 @@ func (s *Service) initializeBeaconChain(
log.Info("Initialized beacon chain genesis state")
// Clear out all pre-genesis data now that the state is initialized.
s.chainStartFetcher.ClearPreGenesisData()
s.cfg.ChainStartFetcher.ClearPreGenesisData()
// Update committee shuffled indices for genesis epoch.
if err := helpers.UpdateCommitteeCache(genesisState, 0 /* genesis epoch */); err != nil {
return nil, err
}
if err := helpers.UpdateProposerIndicesInCache(genesisState, 0 /* genesis epoch */); err != nil {
if err := helpers.UpdateProposerIndicesInCache(genesisState); err != nil {
return nil, err
}
s.opsService.SetGenesisTime(genesisState.GenesisTime())
s.cfg.OpsService.SetGenesisTime(genesisState.GenesisTime())
return genesisState, nil
}
@@ -336,14 +309,14 @@ func (s *Service) initializeBeaconChain(
func (s *Service) Stop() error {
defer s.cancel()
if s.stateGen != nil && s.head != nil && s.head.state != nil {
if err := s.stateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
if s.cfg.StateGen != nil && s.head != nil && s.head.state != nil {
if err := s.cfg.StateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
return err
}
}
// Save initial sync cached blocks to the DB before stop.
return s.beaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks())
return s.cfg.BeaconDB.SaveBlocks(s.ctx, s.getInitSyncBlocks())
}
// Status always returns nil unless there is an error condition that causes
@@ -352,60 +325,42 @@ func (s *Service) Status() error {
if s.genesisRoot == params.BeaconConfig().ZeroHash {
return errors.New("genesis state has not been created")
}
if runtime.NumGoroutine() > s.maxRoutines {
if runtime.NumGoroutine() > s.cfg.MaxRoutines {
return fmt.Errorf("too many goroutines %d", runtime.NumGoroutine())
}
return nil
}
// This gets called when beacon chain is first initialized to save genesis data (state, block, and more) in db.
func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.BeaconState) error {
stateRoot, err := genesisState.HashTreeRoot(ctx)
if err != nil {
return err
func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.BeaconState) error {
if err := s.cfg.BeaconDB.SaveGenesisData(ctx, genesisState); err != nil {
return errors.Wrap(err, "could not save genesis data")
}
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
if err != nil || genesisBlk == nil {
return fmt.Errorf("could not load genesis block: %v", err)
}
genesisBlk := blocks.NewGenesisBlock(stateRoot[:])
genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get genesis block root")
}
s.genesisRoot = genesisBlkRoot
if err := s.beaconDB.SaveBlock(ctx, genesisBlk); err != nil {
return errors.Wrap(err, "could not save genesis block")
}
if err := s.beaconDB.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis state")
}
if err := s.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: 0,
Root: genesisBlkRoot[:],
}); err != nil {
return err
}
s.stateGen.SaveFinalizedState(0, genesisBlkRoot, genesisState)
if err := s.beaconDB.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save head block root")
}
if err := s.beaconDB.SaveGenesisBlockRoot(ctx, genesisBlkRoot); err != nil {
return errors.Wrap(err, "could not save genesis block root")
}
s.cfg.StateGen.SaveFinalizedState(0 /*slot*/, genesisBlkRoot, genesisState)
// Finalized checkpoint at genesis is a zero hash.
genesisCheckpoint := genesisState.FinalizedCheckpoint()
s.justifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.justifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
if err := s.cacheJustifiedStateBalances(ctx, genesisBlkRoot); err != nil {
return err
}
s.prevJustifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = stateTrie.CopyCheckpoint(genesisCheckpoint)
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
if err := s.forkChoiceStore.ProcessBlock(ctx,
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
genesisBlk.Block.Slot,
genesisBlkRoot,
params.BeaconConfig().ZeroHash,
@@ -416,13 +371,12 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState *stateTrie.B
}
s.setHead(genesisBlkRoot, genesisBlk, genesisState)
return nil
}
// This gets called to initialize chain info variables using the finalized checkpoint stored in DB
func (s *Service) initializeChainInfo(ctx context.Context) error {
genesisBlock, err := s.beaconDB.GenesisBlock(ctx)
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not get genesis block from db")
}
@@ -435,7 +389,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
}
s.genesisRoot = genesisBlkRoot
finalized, err := s.beaconDB.FinalizedCheckpoint(ctx)
finalized, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized checkpoint from db")
}
@@ -445,20 +399,20 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
return errors.New("no finalized epoch in the database")
}
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
var finalizedState *stateTrie.BeaconState
var finalizedState iface.BeaconState
finalizedState, err = s.stateGen.Resume(ctx)
finalizedState, err = s.cfg.StateGen.Resume(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
if flags.Get().HeadSync {
headBlock, err := s.beaconDB.HeadBlock(ctx)
headBlock, err := s.cfg.BeaconDB.HeadBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not retrieve head block")
}
headEpoch := helpers.SlotToEpoch(headBlock.Block.Slot)
var epochsSinceFinality uint64
var epochsSinceFinality types.Epoch
if headEpoch > finalized.Epoch {
epochsSinceFinality = headEpoch - finalized.Epoch
}
@@ -469,13 +423,13 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "could not hash head block")
}
finalizedState, err := s.stateGen.Resume(ctx)
finalizedState, err := s.cfg.StateGen.Resume(ctx)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
log.Infof("Regenerating state from the last checkpoint at slot %d to current head slot of %d."+
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block.Slot)
headState, err := s.stateGen.StateByRoot(ctx, headRoot)
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
if err != nil {
return errors.Wrap(err, "could not retrieve head state")
}
@@ -488,7 +442,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
}
}
finalizedBlock, err := s.beaconDB.Block(ctx, finalizedRoot)
finalizedBlock, err := s.cfg.BeaconDB.Block(ctx, finalizedRoot)
if err != nil {
return errors.Wrap(err, "could not get finalized block from db")
}
@@ -505,7 +459,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
// information to fork choice service to initializes fork choice store.
func (s *Service) resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint *ethpb.Checkpoint) {
store := protoarray.New(justifiedCheckpoint.Epoch, finalizedCheckpoint.Epoch, bytesutil.ToBytes32(finalizedCheckpoint.Root))
s.forkChoiceStore = store
s.cfg.ForkChoiceStore = store
}
// This returns true if block has been processed before. Two ways to verify the block has been processed:
@@ -513,9 +467,9 @@ func (s *Service) resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint *eth
// 2.) Check DB.
// Checking 1.) is ten times faster than checking 2.)
func (s *Service) hasBlock(ctx context.Context, root [32]byte) bool {
if s.forkChoiceStore.HasNode(root) {
if s.cfg.ForkChoiceStore.HasNode(root) {
return true
}
return s.beaconDB.HasBlock(ctx, root)
return s.cfg.BeaconDB.HasBlock(ctx, root)
}

View File

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

View File

@@ -18,13 +18,13 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
protodb "github.com/prysmaticlabs/prysm/proto/beacon/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -70,8 +70,10 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
var web3Service *powchain.Service
var err error
bState, _ := testutil.DeterministicGenesisState(t, 10)
pbState, err := stateV0.ProtobufBeaconState(bState.InnerStateUnsafe())
require.NoError(t, err)
err = beaconDB.SavePowchainData(ctx, &protodb.ETH1ChainData{
BeaconState: bState.InnerStateUnsafe(),
BeaconState: pbState,
Trie: &protodb.SparseMerkleTrie{},
CurrentEth1Data: &protodb.LatestETH1Data{
BlockHash: make([]byte, 32),
@@ -86,14 +88,14 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
DepositContainers: []*protodb.DepositContainer{},
})
require.NoError(t, err)
web3Service, err = powchain.New(ctx, &powchain.Web3ServiceConfig{
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
BeaconDB: beaconDB,
HTTPEndpoints: []string{endpoint},
DepositContract: common.Address{},
})
require.NoError(t, err, "Unable to set up web3 service")
opsService, err := attestations.New(ctx, &attestations.Config{Pool: attestations.NewPool()})
opsService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
require.NoError(t, err)
depositCache, err := depositcache.New()
@@ -115,7 +117,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
// Safe a state in stategen to purposes of testing a service stop / shutdown.
require.NoError(t, cfg.StateGen.SaveState(ctx, bytesutil.ToBytes32(bState.FinalizedCheckpoint().Root), bState))
chainService, err := New(ctx, cfg)
chainService, err := NewService(ctx, cfg)
require.NoError(t, err, "Unable to setup chain service")
chainService.genesisTime = time.Unix(1, 0) // non-zero time
@@ -274,14 +276,14 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{beaconDB: beaconDB, stateGen: stategen.New(beaconDB)}
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headBlock, headBlk, "Head block incorrect")
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, c.HeadSlot(), headBlock.Block.Slot, "Head slot incorrect")
r, err := c.HeadRoot(context.Background())
require.NoError(t, err)
@@ -314,11 +316,11 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
c := &Service{beaconDB: beaconDB, stateGen: stategen.New(beaconDB)}
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
assert.DeepEqual(t, genesis, c.head.block)
}
@@ -371,12 +373,12 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
Root: finalizedRoot[:],
}))
c := &Service{beaconDB: beaconDB, stateGen: stategen.New(beaconDB)}
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Since head sync is not triggered, chain is initialized to the last finalization checkpoint.
assert.DeepEqual(t, finalizedBlock, c.head.block)
@@ -397,7 +399,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
require.NoError(t, c.initializeChainInfo(ctx))
s, err = c.HeadState(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Head slot is far beyond the latest finalized checkpoint, head sync is triggered.
assert.DeepEqual(t, headBlock, c.head.block)
@@ -409,8 +411,7 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
s := &Service{
beaconDB: beaconDB,
stateGen: stategen.New(beaconDB),
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
blk := testutil.NewBeaconBlock()
blk.Block.Slot = 1
@@ -418,10 +419,10 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
require.NoError(t, err)
newState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.stateGen.SaveState(ctx, r, newState))
require.NoError(t, s.cfg.StateGen.SaveState(ctx, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, blk, r, newState))
newB, err := s.beaconDB.HeadBlock(ctx)
newB, err := s.cfg.BeaconDB.HeadBlock(ctx)
require.NoError(t, err)
if reflect.DeepEqual(newB, blk) {
t.Error("head block should not be equal")
@@ -432,9 +433,8 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: beaconDB,
}
block := testutil.NewBeaconBlock()
r, err := block.Block.HashTreeRoot()
@@ -451,25 +451,24 @@ func TestServiceStop_SaveCachedBlocks(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
ctx: ctx,
cancel: cancel,
beaconDB: beaconDB,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
stateGen: stategen.New(beaconDB),
}
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))
require.Equal(t, true, s.cfg.BeaconDB.HasBlock(ctx, r))
}
func TestProcessChainStartTime_ReceivedFeed(t *testing.T) {
beaconDB := testDB.SetupDB(t)
service := setupBeaconChain(t, beaconDB)
stateChannel := make(chan *feed.Event, 1)
stateSub := service.stateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
service.processChainStartTime(context.Background(), time.Now())
@@ -483,16 +482,16 @@ func BenchmarkHasBlockDB(b *testing.B) {
beaconDB := testDB.SetupDB(b)
ctx := context.Background()
s := &Service{
beaconDB: beaconDB,
cfg: &Config{BeaconDB: beaconDB},
}
block := testutil.NewBeaconBlock()
require.NoError(b, s.beaconDB.SaveBlock(ctx, block))
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, block))
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
b.ResetTimer()
for i := 0; i < b.N; i++ {
require.Equal(b, true, s.beaconDB.HasBlock(ctx, r), "Block is not in DB")
require.Equal(b, true, s.cfg.BeaconDB.HasBlock(ctx, r), "Block is not in DB")
}
}
@@ -500,20 +499,19 @@ func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
ctx := context.Background()
beaconDB := testDB.SetupDB(b)
s := &Service{
forkChoiceStore: protoarray.New(0, 0, [32]byte{}),
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
beaconDB: beaconDB,
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}}
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}}
beaconState, err := beaconstate.InitializeFromProto(bs)
beaconState, err := stateV0.InitializeFromProto(bs)
require.NoError(b, err)
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, beaconState))
b.ResetTimer()
for i := 0; i < b.N; i++ {
require.Equal(b, true, s.forkChoiceStore.HasNode(r), "Block is not in fork choice store")
require.Equal(b, true, s.cfg.ForkChoiceStore.HasNode(r), "Block is not in fork choice store")
}
}

View File

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

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
@@ -18,7 +19,8 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -27,7 +29,7 @@ import (
// ChainService defines the mock interface for testing
type ChainService struct {
State *stateTrie.BeaconState
State iface.BeaconState
Root []byte
Block *ethpb.SignedBeaconBlock
FinalizedCheckPoint *ethpb.Checkpoint
@@ -47,7 +49,7 @@ type ChainService struct {
ValidAttestation bool
ForkChoiceStore *protoarray.Store
VerifyBlkDescendantErr error
Slot *uint64 // Pointer because 0 is a useful value, so checking against it can be incorrect.
Slot *types.Slot // Pointer because 0 is a useful value, so checking against it can be incorrect.
}
// StateNotifier mocks the same method in the chain service.
@@ -148,7 +150,7 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &stateTrie.BeaconState{}
s.State = &stateV0.BeaconState{}
}
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
@@ -175,7 +177,7 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb
// ReceiveBlockBatch processes blocks in batches from initial-sync.
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, _ [][32]byte) error {
if s.State == nil {
s.State = &stateTrie.BeaconState{}
s.State = &stateV0.BeaconState{}
}
for _, block := range blks {
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
@@ -204,7 +206,7 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sign
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &stateTrie.BeaconState{}
s.State = &stateV0.BeaconState{}
}
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
@@ -229,7 +231,7 @@ func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeac
}
// HeadSlot mocks HeadSlot method in chain service.
func (s *ChainService) HeadSlot() uint64 {
func (s *ChainService) HeadSlot() types.Slot {
if s.State == nil {
return 0
}
@@ -250,7 +252,7 @@ func (s *ChainService) HeadBlock(context.Context) (*ethpb.SignedBeaconBlock, err
}
// HeadState mocks HeadState method in chain service.
func (s *ChainService) HeadState(context.Context) (*stateTrie.BeaconState, error) {
func (s *ChainService) HeadState(context.Context) (iface.BeaconState, error) {
return s.State, nil
}
@@ -285,20 +287,20 @@ func (s *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attest
}
// AttestationPreState mocks AttestationPreState method in chain service.
func (s *ChainService) AttestationPreState(_ context.Context, _ *ethpb.Attestation) (*stateTrie.BeaconState, error) {
func (s *ChainService) AttestationPreState(_ context.Context, _ *ethpb.Attestation) (iface.BeaconState, error) {
return s.State, nil
}
// HeadValidatorsIndices mocks the same method in the chain service.
func (s *ChainService) HeadValidatorsIndices(_ context.Context, epoch uint64) ([]uint64, error) {
func (s *ChainService) HeadValidatorsIndices(_ context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error) {
if s.State == nil {
return []uint64{}, nil
return []types.ValidatorIndex{}, nil
}
return helpers.ActiveValidatorIndices(s.State, epoch)
}
// HeadSeed mocks the same method in the chain service.
func (s *ChainService) HeadSeed(_ context.Context, epoch uint64) ([32]byte, error) {
func (s *ChainService) HeadSeed(_ context.Context, epoch types.Epoch) ([32]byte, error) {
return helpers.Seed(s.State, epoch, params.BeaconConfig().DomainBeaconAttester)
}
@@ -323,11 +325,11 @@ func (s *ChainService) GenesisValidatorRoot() [32]byte {
}
// CurrentSlot mocks the same method in the chain service.
func (s *ChainService) CurrentSlot() uint64 {
func (s *ChainService) CurrentSlot() types.Slot {
if s.Slot != nil {
return *s.Slot
}
return uint64(time.Now().Unix()-s.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot
return types.Slot(uint64(time.Now().Unix()-s.Genesis.Unix()) / params.BeaconConfig().SecondsPerSlot)
}
// Participation mocks the same method in the chain service.
@@ -380,3 +382,8 @@ func (s *ChainService) VerifyFinalizedConsistency(_ context.Context, r []byte) e
}
return nil
}
// ChainHeads mocks ChainHeads and always return nil.
func (s *ChainService) ChainHeads() ([][32]byte, []types.Slot) {
return [][32]byte{}, []types.Slot{}
}

View File

@@ -14,7 +14,7 @@ import (
// Reference design: https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/weak-subjectivity.md#weak-subjectivity-sync-procedure
func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
// TODO(7342): Remove the following to fully use weak subjectivity in production.
if len(s.wsRoot) == 0 || s.wsEpoch == 0 {
if s.cfg.WeakSubjectivityCheckpt == nil || len(s.cfg.WeakSubjectivityCheckpt.Root) == 0 || s.cfg.WeakSubjectivityCheckpt.Epoch == 0 {
return nil
}
@@ -23,28 +23,28 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
if s.wsVerified {
return nil
}
if s.wsEpoch > s.finalizedCheckpt.Epoch {
if s.cfg.WeakSubjectivityCheckpt.Epoch > s.finalizedCheckpt.Epoch {
return nil
}
r := bytesutil.ToBytes32(s.wsRoot)
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.wsEpoch)
r := bytesutil.ToBytes32(s.cfg.WeakSubjectivityCheckpt.Root)
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
// Save initial sync cached blocks to DB.
if err := s.beaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
// A node should have the weak subjectivity block in the DB.
if !s.beaconDB.HasBlock(ctx, r) {
if !s.cfg.BeaconDB.HasBlock(ctx, r) {
return fmt.Errorf("node does not have root in DB: %#x", r)
}
startSlot, err := helpers.StartSlot(s.wsEpoch)
startSlot, err := helpers.StartSlot(s.cfg.WeakSubjectivityCheckpt.Epoch)
if err != nil {
return err
}
// A node should have the weak subjectivity block corresponds to the correct epoch in the DB.
filter := filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(startSlot + params.BeaconConfig().SlotsPerEpoch)
roots, err := s.beaconDB.BlockRoots(ctx, filter)
roots, err := s.cfg.BeaconDB.BlockRoots(ctx, filter)
if err != nil {
return err
}
@@ -56,5 +56,5 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
}
}
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.wsEpoch)
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
}

View File

@@ -4,8 +4,10 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -21,9 +23,8 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
tests := []struct {
wsVerified bool
wantErr bool
wsRoot [32]byte
wsEpoch uint64
finalizedEpoch uint64
checkpt *ethpb.Checkpoint
finalizedEpoch types.Epoch
errString string
name string
}{
@@ -33,37 +34,34 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
},
{
name: "already verified",
wsEpoch: 2,
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 2,
wsVerified: true,
wantErr: false,
},
{
name: "not yet to verify, ws epoch higher than finalized epoch",
wsEpoch: 2,
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 1,
wantErr: false,
},
{
name: "can't find the block in DB",
wsEpoch: 1,
wsRoot: [32]byte{'a'},
checkpt: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: 1},
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in DB",
},
{
name: "can't find the block corresponds to ws epoch in DB",
wsEpoch: 2,
wsRoot: r, // Root belongs in epoch 1.
checkpt: &ethpb.Checkpoint{Root: r[:], Epoch: 2}, // Root belongs in epoch 1.
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in db corresponding to epoch",
},
{
name: "can verify and pass",
wsEpoch: 1,
wsRoot: r,
checkpt: &ethpb.Checkpoint{Root: r[:], Epoch: 1},
finalizedEpoch: 3,
wantErr: false,
},
@@ -71,9 +69,7 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
beaconDB: beaconDB,
wsRoot: tt.wsRoot[:],
wsEpoch: tt.wsEpoch,
cfg: &Config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
wsVerified: tt.wsVerified,
finalizedCheckpt: &ethpb.Checkpoint{Epoch: tt.finalizedEpoch},
}

View File

@@ -1,8 +1,8 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
# gazelle:ignore committee_disabled.go
# gazelle:ignore proposer_indices_disabled.go
# gazelle:exclude committee_disabled.go
# gazelle:exclude proposer_indices_disabled.go
go_library(
name = "go_default_library",
srcs = [
@@ -11,13 +11,13 @@ go_library(
"committees.go",
"common.go",
"doc.go",
"proposer_indices_type.go",
"skip_slot_cache.go",
"subnet_ids.go",
"proposer_indices_type.go",
] + select({
"//fuzz:fuzzing_enabled": [
"committee_disabled.go",
"proposer_indices_disabled.go"
"proposer_indices_disabled.go",
],
"//conditions:default": [
"committee.go",
@@ -31,9 +31,8 @@ go_library(
"//tools:__subpackages__",
],
deps = [
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/featureconfig:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
@@ -41,6 +40,7 @@ go_library(
"@com_github_patrickmn_go_cache//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
"@io_opencensus_go//trace:go_default_library",
@@ -52,25 +52,26 @@ go_test(
size = "small",
srcs = [
"attestation_data_test.go",
"cache_test.go",
"checkpoint_state_test.go",
"committee_fuzz_test.go",
"committee_test.go",
"cache_test.go",
"proposer_indices_test.go",
"skip_slot_cache_test.go",
"subnet_ids_test.go",
"proposer_indices_test.go"
],
embed = [":go_default_library"],
deps = [
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
],
)

View File

@@ -11,7 +11,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"k8s.io/client-go/tools/cache"
)
@@ -98,7 +98,7 @@ func (c *AttestationCache) Get(ctx context.Context, req *ethpb.AttestationDataRe
if exists && item != nil && item.(*attestationReqResWrapper).res != nil {
attestationCacheHit.Inc()
return state.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
return stateV0.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
}
attestationCacheMiss.Inc()
return nil, nil

View File

@@ -2,12 +2,8 @@ package cache
import (
"testing"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
)
func TestMain(m *testing.M) {
resetCfg := featureconfig.InitWithReset(&featureconfig.Flags{EnableEth1DataVoteCache: true})
defer resetCfg()
m.Run()
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
@@ -47,7 +47,7 @@ func NewCheckpointStateCache() *CheckpointStateCache {
// StateByCheckpoint fetches state by checkpoint. Returns true with a
// reference to the CheckpointState info, if exists. Otherwise returns false, nil.
func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTrie.BeaconState, error) {
func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (iface.BeaconState, error) {
c.lock.RLock()
defer c.lock.RUnlock()
h, err := hashutil.HashProto(cp)
@@ -60,7 +60,7 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
if exists && item != nil {
checkpointStateHit.Inc()
// Copy here is unnecessary since the return will only be used to verify attestation signature.
return item.(*stateTrie.BeaconState), nil
return item.(iface.BeaconState), nil
}
checkpointStateMiss.Inc()
@@ -69,7 +69,7 @@ func (c *CheckpointStateCache) StateByCheckpoint(cp *ethpb.Checkpoint) (*stateTr
// AddCheckpointState adds CheckpointState object to the cache. This method also trims the least
// recently added CheckpointState object if the cache size has ready the max cache size limit.
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s *stateTrie.BeaconState) error {
func (c *CheckpointStateCache) AddCheckpointState(cp *ethpb.Checkpoint, s iface.ReadOnlyBeaconState) error {
c.lock.Lock()
defer c.lock.Unlock()
h, err := hashutil.HashProto(cp)

View File

@@ -4,8 +4,10 @@ import (
"testing"
"github.com/gogo/protobuf/proto"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -17,7 +19,7 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
cache := NewCheckpointStateCache()
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st, err := stateV0.InitializeFromProto(&pb.BeaconState{
GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:],
Slot: 64,
})
@@ -25,19 +27,23 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
state, err := cache.StateByCheckpoint(cp1)
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Expected state not to exist in empty cache")
assert.Equal(t, iface.BeaconState(nil), state, "Expected state not to exist in empty cache")
require.NoError(t, cache.AddCheckpointState(cp1, st))
state, err = cache.StateByCheckpoint(cp1)
require.NoError(t, err)
if !proto.Equal(state.InnerStateUnsafe(), st.InnerStateUnsafe()) {
pbState1, err := stateV0.ProtobufBeaconState(state.InnerStateUnsafe())
require.NoError(t, err)
pbState2, err := stateV0.ProtobufBeaconState(st.InnerStateUnsafe())
require.NoError(t, err)
if !proto.Equal(pbState1, pbState2) {
t.Error("incorrectly cached state")
}
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
st2, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st2, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 128,
})
require.NoError(t, err)
@@ -54,14 +60,14 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
func TestCheckpointStateCache_MaxSize(t *testing.T) {
c := NewCheckpointStateCache()
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
st, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 0,
})
require.NoError(t, err)
for i := uint64(0); i < uint64(maxCheckpointStateSize+100); i++ {
require.NoError(t, st.SetSlot(i))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: i, Root: make([]byte, 32)}, st))
require.NoError(t, st.SetSlot(types.Slot(i)))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: types.Epoch(i), Root: make([]byte, 32)}, st))
}
assert.Equal(t, maxCheckpointStateSize, len(c.cache.Keys()))

View File

@@ -8,6 +8,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"k8s.io/client-go/tools/cache"
@@ -55,7 +56,7 @@ func NewCommitteesCache() *CommitteeCache {
// Committee fetches the shuffled indices by slot and committee index. Every list of indices
// represent one committee. Returns true if the list exists with slot and committee index. Otherwise returns false, nil.
func (c *CommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]uint64, error) {
func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.CommitteeIndex) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
@@ -77,11 +78,11 @@ func (c *CommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]
}
committeeCountPerSlot := uint64(1)
if item.CommitteeCount/params.BeaconConfig().SlotsPerEpoch > 1 {
committeeCountPerSlot = item.CommitteeCount / params.BeaconConfig().SlotsPerEpoch
if item.CommitteeCount/uint64(params.BeaconConfig().SlotsPerEpoch) > 1 {
committeeCountPerSlot = item.CommitteeCount / uint64(params.BeaconConfig().SlotsPerEpoch)
}
indexOffSet := index + (slot%params.BeaconConfig().SlotsPerEpoch)*committeeCountPerSlot
indexOffSet := uint64(index) + uint64(slot.ModSlot(params.BeaconConfig().SlotsPerEpoch).Mul(committeeCountPerSlot))
start, end := startEndIndices(item, indexOffSet)
if end > uint64(len(item.ShuffledIndices)) || end < start {
@@ -105,7 +106,7 @@ func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))

View File

@@ -3,6 +3,8 @@
// This file is used in fuzzer builds to bypass global committee caches.
package cache
import types "github.com/prysmaticlabs/eth2-types"
// FakeCommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type FakeCommitteeCache struct {
}
@@ -14,7 +16,7 @@ func NewCommitteesCache() *FakeCommitteeCache {
// Committee fetches the shuffled indices by slot and committee index. Every list of indices
// represent one committee. Returns true if the list exists with slot and committee index. Otherwise returns false, nil.
func (c *FakeCommitteeCache) Committee(slot uint64, seed [32]byte, index uint64) ([]uint64, error) {
func (c *FakeCommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.CommitteeIndex) ([]types.ValidatorIndex, error) {
return nil, nil
}
@@ -25,12 +27,12 @@ func (c *FakeCommitteeCache) AddCommitteeShuffledList(committees *Committees) er
}
// AddProposerIndicesList updates the committee shuffled list with proposer indices.
func (c *FakeCommitteeCache) AddProposerIndicesList(seed [32]byte, indices []uint64) error {
func (c *FakeCommitteeCache) AddProposerIndicesList(seed [32]byte, indices []types.ValidatorIndex) error {
return nil
}
// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *FakeCommitteeCache) ActiveIndices(seed [32]byte) ([]uint64, error) {
func (c *FakeCommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}
@@ -40,7 +42,7 @@ func (c *FakeCommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
}
// ProposerIndices returns the proposer indices of a given seed.
func (c *FakeCommitteeCache) ProposerIndices(seed [32]byte) ([]uint64, error) {
func (c *FakeCommitteeCache) ProposerIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}

View File

@@ -6,6 +6,7 @@ import (
"strconv"
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -16,7 +17,7 @@ func TestCommitteeKeyFn_OK(t *testing.T) {
item := &Committees{
CommitteeCount: 1,
Seed: [32]byte{'A'},
ShuffledIndices: []uint64{1, 2, 3, 4, 5},
ShuffledIndices: []types.ValidatorIndex{1, 2, 3, 4, 5},
}
k, err := committeeKeyFn(item)
@@ -33,13 +34,13 @@ func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{
ShuffledIndices: []uint64{1, 2, 3, 4, 5, 6},
ShuffledIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6},
Seed: [32]byte{'A'},
CommitteeCount: 3,
}
slot := params.BeaconConfig().SlotsPerEpoch
committeeIndex := uint64(1)
committeeIndex := types.CommitteeIndex(1)
indices, err := cache.Committee(slot, item.Seed, committeeIndex)
require.NoError(t, err)
if indices != nil {
@@ -47,18 +48,18 @@ func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
}
require.NoError(t, cache.AddCommitteeShuffledList(item))
wantedIndex := uint64(0)
wantedIndex := types.CommitteeIndex(0)
indices, err = cache.Committee(slot, item.Seed, wantedIndex)
require.NoError(t, err)
start, end := startEndIndices(item, wantedIndex)
start, end := startEndIndices(item, uint64(wantedIndex))
assert.DeepEqual(t, item.ShuffledIndices[start:end], indices)
}
func TestCommitteeCache_ActiveIndices(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
indices, err := cache.ActiveIndices(item.Seed)
require.NoError(t, err)
if indices != nil {
@@ -75,7 +76,7 @@ func TestCommitteeCache_ActiveIndices(t *testing.T) {
func TestCommitteeCache_ActiveCount(t *testing.T) {
cache := NewCommitteesCache()
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
count, err := cache.ActiveIndicesCount(item.Seed)
require.NoError(t, err)
assert.Equal(t, 0, count, "Expected active count not to exist in empty cache")
@@ -119,8 +120,8 @@ func TestCommitteeCacheOutOfRange(t *testing.T) {
err := cache.CommitteeCache.Add(&Committees{
CommitteeCount: 1,
Seed: seed,
ShuffledIndices: []uint64{0},
SortedIndices: []uint64{},
ShuffledIndices: []types.ValidatorIndex{0},
SortedIndices: []types.ValidatorIndex{},
})
require.NoError(t, err)

View File

@@ -1,6 +1,10 @@
package cache
import "errors"
import (
"errors"
types "github.com/prysmaticlabs/eth2-types"
)
// ErrNotCommittee will be returned when a cache object is not a pointer to
// a Committee struct.
@@ -10,6 +14,6 @@ var ErrNotCommittee = errors.New("object is not a committee struct")
type Committees struct {
CommitteeCount uint64
Seed [32]byte
ShuffledIndices []uint64
SortedIndices []uint64
ShuffledIndices []types.ValidatorIndex
SortedIndices []types.ValidatorIndex
}

View File

@@ -8,7 +8,7 @@ import (
var (
// maxCacheSize is 4x of the epoch length for additional cache padding.
// Requests should be only accessing committees within defined epoch length.
maxCacheSize = 4 * params.BeaconConfig().SlotsPerEpoch
maxCacheSize = uint64(4 * params.BeaconConfig().SlotsPerEpoch)
)
// trim the FIFO queue to the maxSize.

View File

@@ -90,7 +90,9 @@ func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blo
defer dc.depositsLock.Unlock()
// Keep the slice sorted on insertion in order to avoid costly sorting on retrieval.
heightIdx := sort.Search(len(dc.deposits), func(i int) bool { return dc.deposits[i].Index >= index })
newDeposits := append([]*dbpb.DepositContainer{{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}}, dc.deposits[heightIdx:]...)
newDeposits := append(
[]*dbpb.DepositContainer{{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}},
dc.deposits[heightIdx:]...)
dc.deposits = append(dc.deposits[:heightIdx], newDeposits...)
historicalDepositsCount.Inc()
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
types "github.com/prysmaticlabs/eth2-types"
"k8s.io/client-go/tools/cache"
)
@@ -75,7 +76,7 @@ func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.ProposerIndicesCache.GetByKey(key(r))

View File

@@ -3,6 +3,8 @@
// This file is used in fuzzer builds to bypass proposer indices caches.
package cache
import types "github.com/prysmaticlabs/eth2-types"
// FakeProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
type FakeProposerIndicesCache struct {
}
@@ -19,7 +21,7 @@ func (c *FakeProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error
}
// ProposerIndices returns the proposer indices of a block root seed.
func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]uint64, error) {
func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
return nil, nil
}

View File

@@ -4,6 +4,7 @@ import (
"strconv"
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -12,7 +13,7 @@ import (
func TestProposerKeyFn_OK(t *testing.T) {
item := &ProposerIndices{
BlockRoot: [32]byte{'A'},
ProposerIndices: []uint64{1, 2, 3, 4, 5},
ProposerIndices: []types.ValidatorIndex{1, 2, 3, 4, 5},
}
k, err := proposerIndicesKeyFn(item)
@@ -48,7 +49,7 @@ func TestProposerCache_AddProposerIndicesList(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, true, has)
item := &ProposerIndices{BlockRoot: [32]byte{'B'}, ProposerIndices: []uint64{1, 2, 3, 4, 5, 6}}
item := &ProposerIndices{BlockRoot: [32]byte{'B'}, ProposerIndices: []types.ValidatorIndex{1, 2, 3, 4, 5, 6}}
require.NoError(t, cache.AddProposerIndices(item))
received, err = cache.ProposerIndices(item.BlockRoot)

View File

@@ -1,6 +1,10 @@
package cache
import "errors"
import (
"errors"
types "github.com/prysmaticlabs/eth2-types"
)
// ErrNotProposerIndices will be returned when a cache object is not a pointer to
// a ProposerIndices struct.
@@ -9,5 +13,5 @@ var ErrNotProposerIndices = errors.New("object is not a proposer indices struct"
// ProposerIndices defines the cached struct for proposer indices.
type ProposerIndices struct {
BlockRoot [32]byte
ProposerIndices []uint64
ProposerIndices []types.ValidatorIndex
}

View File

@@ -9,7 +9,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"go.opencensus.io/trace"
)
@@ -57,7 +57,7 @@ func (c *SkipSlotCache) Disable() {
// Get waits for any in progress calculation to complete before returning a
// cached response, if any.
func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (*stateTrie.BeaconState, error) {
func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "skipSlotCache.Get")
defer span.End()
if c.disabled {
@@ -97,7 +97,7 @@ func (c *SkipSlotCache) Get(ctx context.Context, r [32]byte) (*stateTrie.BeaconS
if exists && item != nil {
skipSlotCacheHit.Inc()
span.AddAttributes(trace.BoolAttribute("hit", true))
return item.(*stateTrie.BeaconState).Copy(), nil
return item.(iface.BeaconState).Copy(), nil
}
skipSlotCacheMiss.Inc()
span.AddAttributes(trace.BoolAttribute("hit", false))
@@ -136,7 +136,7 @@ func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) error {
}
// Put the response in the cache.
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state *stateTrie.BeaconState) error {
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state iface.BeaconState) error {
if c.disabled {
return nil
}

View File

@@ -5,7 +5,8 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -18,11 +19,11 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
r := [32]byte{'a'}
state, err := c.Get(ctx, r)
require.NoError(t, err)
assert.Equal(t, (*stateTrie.BeaconState)(nil), state, "Empty cache returned an object")
assert.Equal(t, iface.BeaconState(nil), state, "Empty cache returned an object")
require.NoError(t, c.MarkInProgress(r))
state, err = stateTrie.InitializeFromProto(&pb.BeaconState{
state, err = stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 10,
})
require.NoError(t, err)

View File

@@ -6,6 +6,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/patrickmn/go-cache"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
@@ -25,7 +26,7 @@ var SubnetIDs = newSubnetIDs()
func newSubnetIDs() *subnetIDs {
// Given a node can calculate committee assignments of current epoch and next epoch.
// Max size is set to 2 epoch length.
cacheSize := int(params.BeaconConfig().MaxCommitteesPerSlot * params.BeaconConfig().SlotsPerEpoch * 2)
cacheSize := int(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxCommitteesPerSlot * 2))
attesterCache, err := lru.New(cacheSize)
if err != nil {
panic(err)
@@ -34,14 +35,14 @@ func newSubnetIDs() *subnetIDs {
if err != nil {
panic(err)
}
epochDuration := time.Duration(params.BeaconConfig().SlotsPerEpoch * params.BeaconConfig().SecondsPerSlot)
epochDuration := time.Duration(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
subLength := epochDuration * time.Duration(params.BeaconConfig().EpochsPerRandomSubnetSubscription)
persistentCache := cache.New(subLength*time.Second, epochDuration*time.Second)
return &subnetIDs{attester: attesterCache, aggregator: aggregatorCache, persistentSubnets: persistentCache}
}
// AddAttesterSubnetID adds the subnet index for subscribing subnet for the attester of a given slot.
func (s *subnetIDs) AddAttesterSubnetID(slot, subnetID uint64) {
func (s *subnetIDs) AddAttesterSubnetID(slot types.Slot, subnetID uint64) {
s.attesterLock.Lock()
defer s.attesterLock.Unlock()
@@ -54,7 +55,7 @@ func (s *subnetIDs) AddAttesterSubnetID(slot, subnetID uint64) {
}
// GetAttesterSubnetIDs gets the subnet IDs for subscribed subnets for attesters of the slot.
func (s *subnetIDs) GetAttesterSubnetIDs(slot uint64) []uint64 {
func (s *subnetIDs) GetAttesterSubnetIDs(slot types.Slot) []uint64 {
s.attesterLock.RLock()
defer s.attesterLock.RUnlock()
@@ -69,7 +70,7 @@ func (s *subnetIDs) GetAttesterSubnetIDs(slot uint64) []uint64 {
}
// AddAggregatorSubnetID adds the subnet ID for subscribing subnet for the aggregator of a given slot.
func (s *subnetIDs) AddAggregatorSubnetID(slot, subnetID uint64) {
func (s *subnetIDs) AddAggregatorSubnetID(slot types.Slot, subnetID uint64) {
s.aggregatorLock.Lock()
defer s.aggregatorLock.Unlock()
@@ -82,7 +83,7 @@ func (s *subnetIDs) AddAggregatorSubnetID(slot, subnetID uint64) {
}
// GetAggregatorSubnetIDs gets the subnet IDs for subscribing subnet for aggregator of the slot.
func (s *subnetIDs) GetAggregatorSubnetIDs(slot uint64) []uint64 {
func (s *subnetIDs) GetAggregatorSubnetIDs(slot types.Slot) []uint64 {
s.aggregatorLock.RLock()
defer s.aggregatorLock.RUnlock()
@@ -132,3 +133,22 @@ func (s *subnetIDs) AddPersistentCommittee(pubkey []byte, comIndex []uint64, dur
s.persistentSubnets.Set(string(pubkey), comIndex, duration)
}
// EmptyAllCaches empties out all the related caches and flushes any stored
// entries on them. This should only ever be used for testing, in normal
// production, handling of the relevant subnets for each role is done
// separately.
func (s *subnetIDs) EmptyAllCaches() {
// Clear the caches.
s.attesterLock.Lock()
s.attester.Purge()
s.attesterLock.Unlock()
s.aggregatorLock.Lock()
s.aggregator.Purge()
s.aggregatorLock.Unlock()
s.subnetsLock.Lock()
s.persistentSubnets.Flush()
s.subnetsLock.Unlock()
}

View File

@@ -3,13 +3,14 @@ package cache
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestSubnetIDsCache_RoundTrip(t *testing.T) {
c := newSubnetIDs()
slot := uint64(100)
slot := types.Slot(100)
committeeIDs := c.GetAggregatorSubnetIDs(slot)
assert.Equal(t, 0, len(committeeIDs), "Empty cache returned an object")

View File

@@ -26,7 +26,8 @@ go_library(
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bls:go_default_library",
@@ -40,6 +41,7 @@ go_library(
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
@@ -70,7 +72,8 @@ go_test(
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/p2p/types:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/aggregation:go_default_library",
"//shared/aggregation/attestations:go_default_library",
@@ -84,6 +87,7 @@ go_test(
"//shared/trieutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -1,14 +1,14 @@
package blocks
import (
"bytes"
"context"
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
@@ -20,11 +20,11 @@ import (
// records.
func ProcessAttestations(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
var err error
@@ -68,9 +68,9 @@ func ProcessAttestations(
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
func ProcessAttestation(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
beaconState, err := ProcessAttestationNoVerifySignature(ctx, beaconState, att)
if err != nil {
return nil, err
@@ -82,11 +82,11 @@ func ProcessAttestation(
// records. The only difference would be that the attestation signature would not be verified.
func ProcessAttestationsNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
var err error
@@ -99,44 +99,50 @@ func ProcessAttestationsNoVerifySignature(
return beaconState, nil
}
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerifySignature(
// VerifyAttestationNoVerifySignature verifies the attestation without verifying the attestation signature. This is
// used before processing attestation with the beacon state.
func VerifyAttestationNoVerifySignature(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.ReadOnlyBeaconState,
att *ethpb.Attestation,
) (*stateTrie.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationNoVerifySignature")
defer span.End()
if err := helpers.ValidateNilAttestation(att); err != nil {
return nil, err
}
currEpoch := helpers.SlotToEpoch(beaconState.Slot())
var prevEpoch uint64
if currEpoch == 0 {
prevEpoch = 0
} else {
prevEpoch = currEpoch - 1
return err
}
currEpoch := helpers.CurrentEpoch(beaconState)
prevEpoch := helpers.PrevEpoch(beaconState)
data := att.Data
if data.Target.Epoch != prevEpoch && data.Target.Epoch != currEpoch {
return nil, fmt.Errorf(
return fmt.Errorf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
data.Target.Epoch,
prevEpoch,
currEpoch,
)
}
if data.Target.Epoch == currEpoch {
if !beaconState.MatchCurrentJustifiedCheckpoint(data.Source) {
return errors.New("source check point not equal to current justified checkpoint")
}
} else {
if !beaconState.MatchPreviousJustifiedCheckpoint(data.Source) {
return errors.New("source check point not equal to previous justified checkpoint")
}
}
if err := helpers.ValidateSlotTargetEpoch(att.Data); err != nil {
return nil, err
return err
}
s := att.Data.Slot
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
if !minInclusionCheck {
return nil, fmt.Errorf(
return fmt.Errorf(
"attestation slot %d + inclusion delay %d > state slot %d",
s,
params.BeaconConfig().MinAttestationInclusionDelay,
@@ -144,7 +150,7 @@ func ProcessAttestationNoVerifySignature(
)
}
if !epochInclusionCheck {
return nil, fmt.Errorf(
return fmt.Errorf(
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
beaconState.Slot(),
s,
@@ -153,17 +159,47 @@ func ProcessAttestationNoVerifySignature(
}
activeValidatorCount, err := helpers.ActiveValidatorCount(beaconState, att.Data.Target.Epoch)
if err != nil {
return nil, err
return err
}
c := helpers.SlotCommitteeCount(activeValidatorCount)
if att.Data.CommitteeIndex >= c {
return nil, fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
if uint64(att.Data.CommitteeIndex) >= c {
return fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
}
if err := helpers.VerifyAttestationBitfieldLengths(beaconState, att); err != nil {
return nil, errors.Wrap(err, "could not verify attestation bitfields")
return errors.Wrap(err, "could not verify attestation bitfields")
}
// Verify attesting indices are correct.
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return err
}
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, att, committee)
if err != nil {
return err
}
return attestationutil.IsValidAttestationIndices(ctx, indexedAtt)
}
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
// method is used to validate attestations whose signatures have already been verified.
func ProcessAttestationNoVerifySignature(
ctx context.Context,
beaconState iface.BeaconState,
att *ethpb.Attestation,
) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
defer span.End()
if err := VerifyAttestationNoVerifySignature(ctx, beaconState, att); err != nil {
return nil, err
}
currEpoch := helpers.CurrentEpoch(beaconState)
data := att.Data
s := att.Data.Slot
proposerIndex, err := helpers.BeaconProposerIndex(beaconState)
if err != nil {
return nil, err
@@ -175,107 +211,22 @@ func ProcessAttestationNoVerifySignature(
ProposerIndex: proposerIndex,
}
var ffgSourceEpoch uint64
var ffgSourceRoot []byte
var ffgTargetEpoch uint64
if data.Target.Epoch == currEpoch {
ffgSourceEpoch = beaconState.CurrentJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.CurrentJustifiedCheckpoint().Root
ffgTargetEpoch = currEpoch
if err := beaconState.AppendCurrentEpochAttestations(pendingAtt); err != nil {
return nil, err
}
} else {
ffgSourceEpoch = beaconState.PreviousJustifiedCheckpoint().Epoch
ffgSourceRoot = beaconState.PreviousJustifiedCheckpoint().Root
ffgTargetEpoch = prevEpoch
if err := beaconState.AppendPreviousEpochAttestations(pendingAtt); err != nil {
return nil, err
}
}
if data.Source.Epoch != ffgSourceEpoch {
return nil, fmt.Errorf("expected source epoch %d, received %d", ffgSourceEpoch, data.Source.Epoch)
}
if !bytes.Equal(data.Source.Root, ffgSourceRoot) {
return nil, fmt.Errorf("expected source root %#x, received %#x", ffgSourceRoot, data.Source.Root)
}
if data.Target.Epoch != ffgTargetEpoch {
return nil, fmt.Errorf("expected target epoch %d, received %d", ffgTargetEpoch, data.Target.Epoch)
}
// Verify attesting indices are correct.
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
if err != nil {
return nil, err
}
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, att, committee)
if err != nil {
return nil, err
}
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 {
func VerifyAttestationSignature(ctx context.Context, beaconState iface.ReadOnlyBeaconState, att *ethpb.Attestation) error {
if err := helpers.ValidateNilAttestation(att); err != nil {
return err
}
@@ -306,21 +257,26 @@ func VerifyAttestationSignature(ctx context.Context, beaconState *stateTrie.Beac
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
// signing_root = compute_signing_root(indexed_attestation.data, domain)
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.BeaconState, indexedAtt *ethpb.IndexedAttestation) error {
func VerifyIndexedAttestation(ctx context.Context, beaconState iface.ReadOnlyBeaconState, indexedAtt *ethpb.IndexedAttestation) error {
ctx, span := trace.StartSpan(ctx, "core.VerifyIndexedAttestation")
defer span.End()
if err := attestationutil.IsValidAttestationIndices(ctx, indexedAtt); err != nil {
return err
}
domain, err := helpers.Domain(beaconState.Fork(), indexedAtt.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
domain, err := helpers.Domain(
beaconState.Fork(),
indexedAtt.Data.Target.Epoch,
params.BeaconConfig().DomainBeaconAttester,
beaconState.GenesisValidatorRoot(),
)
if err != nil {
return err
}
indices := indexedAtt.AttestingIndices
var pubkeys []bls.PublicKey
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
pubkeyAtIdx := beaconState.PubkeyAtIndex(types.ValidatorIndex(indices[i]))
pk, err := bls.PublicKeyFromBytes(pubkeyAtIdx[:])
if err != nil {
return errors.Wrap(err, "could not deserialize validator public key")
@@ -329,23 +285,3 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState *stateTrie.Beacon
}
return attestationutil.VerifyIndexedAttestationSig(ctx, indexedAtt, pubkeys, domain)
}
// Inner method to verify attestations. This abstraction allows for the domain to be provided as an
// argument.
func verifyAttestationsSigWithDomain(ctx context.Context, beaconState *stateTrie.BeaconState, atts []*ethpb.Attestation, domain []byte) error {
if len(atts) == 0 {
return nil
}
set, err := createAttestationSignatureSet(ctx, beaconState, atts, domain)
if err != nil {
return err
}
verify, err := set.Verify()
if err != nil {
return errors.Errorf("got error in multiple verification: %v", err)
}
if !verify {
return errors.New("one or more attestation signatures did not verify")
}
return nil
}

View File

@@ -6,9 +6,13 @@ import (
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
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"
)
@@ -33,7 +37,7 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
if err := spb.UnmarshalSSZ(stateData); err != nil {
t.Fatal(err)
}
st, err := state.InitializeFromProtoUnsafe(spb)
st, err := stateV0.InitializeFromProtoUnsafe(spb)
if err != nil {
t.Fatal(err)
}
@@ -42,3 +46,35 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
_, err = blocks.ProcessAttestationNoVerifySignature(ctx, st, att)
require.ErrorContains(t, "committee index 1 >= committee count 1", err)
}
// Regression introduced in https://github.com/prysmaticlabs/prysm/pull/8566.
func TestVerifyAttestationNoVerifySignature_IncorrectSourceEpoch(t *testing.T) {
// Attestation with an empty signature
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 99, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NotEqual(t, nil, err)
}

View File

@@ -5,11 +5,12 @@ import (
"fmt"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/aggregation"
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
@@ -67,7 +68,7 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
@@ -80,14 +81,13 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
}
func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
aggBits := bitfield.NewBitlist(3)
attestations := []*ethpb.Attestation{
{
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
AggregationBits: bitfield.Bitlist{0x09},
},
}
b := testutil.NewBeaconBlock()
@@ -101,24 +101,13 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.CurrentEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
want := "source check point not equal to current justified checkpoint"
_, 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)
}
@@ -145,30 +134,19 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
},
}
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch + params.BeaconConfig().MinAttestationInclusionDelay)
err := beaconState.SetSlot(beaconState.Slot() + 2*params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err)
pfc := beaconState.PreviousJustifiedCheckpoint()
pfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
require.NoError(t, beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
want := fmt.Sprintf(
"expected source epoch %d, received %d",
helpers.PrevEpoch(beaconState),
attestations[0].Data.Source.Epoch,
)
want := "source check point not equal to previous justified checkpoint"
_, 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.Target.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
want = fmt.Sprintf(
"expected source root %#x, received %#x",
beaconState.CurrentJustifiedCheckpoint().Root,
attestations[0].Data.Source.Root,
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
assert.ErrorContains(t, want, err)
}
@@ -197,7 +175,7 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
@@ -222,7 +200,7 @@ func TestProcessAttestations_OK(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
require.NoError(t, err)
@@ -264,7 +242,7 @@ func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = bytesutil.PadTo([]byte("hello-world"), 32)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
@@ -327,7 +305,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
require.NoError(t, err)
@@ -378,7 +356,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch(t *testing.T) {
func TestVerifyAttestationNoVerifySignature_IncorrectSlotTargetEpoch(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 1)
att := testutil.HydrateAttestation(&ethpb.Attestation{
@@ -388,7 +366,7 @@ func TestProcessAttestationsNoVerify_IncorrectSlotTargetEpoch(t *testing.T) {
},
})
wanted := "slot 32 does not match target epoch 0"
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.ErrorContains(t, wanted, err)
}
@@ -417,13 +395,44 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
_, err = blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
func TestVerifyAttestationNoVerifySignature_OK(t *testing.T) {
// Attestation with an empty signature
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
zeroSig := [96]byte{}
att.Signature = zeroSig[:]
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
assert.NoError(t, err)
}
func TestVerifyAttestationNoVerifySignature_BadAttIdx(t *testing.T) {
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
@@ -443,8 +452,8 @@ func TestProcessAttestationsNoVerify_BadAttIdx(t *testing.T) {
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
_, err := blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
require.ErrorContains(t, "committee index 100 >= committee count 1", err)
}
@@ -457,7 +466,7 @@ func TestConvertToIndexed_OK(t *testing.T) {
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
@@ -503,7 +512,7 @@ func TestConvertToIndexed_OK(t *testing.T) {
}
func TestVerifyIndexedAttestation_OK(t *testing.T) {
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
@@ -515,7 +524,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
}
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 5,
Validators: validators,
Fork: &pb.Fork{
@@ -596,13 +605,13 @@ func TestValidateIndexedAttestation_AboveMaxLength(t *testing.T) {
indexedAtt1.AttestingIndices[i] = i
indexedAtt1.Data = &ethpb.AttestationData{
Target: &ethpb.Checkpoint{
Epoch: i,
Epoch: types.Epoch(i),
},
}
}
want := "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE"
err := blocks.VerifyIndexedAttestation(context.Background(), &stateTrie.BeaconState{}, indexedAtt1)
err := blocks.VerifyIndexedAttestation(context.Background(), &stateV0.BeaconState{}, indexedAtt1)
assert.ErrorContains(t, want, err)
}
@@ -648,71 +657,9 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
assert.ErrorContains(t, want, err)
}
func TestVerifyAttestations_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: keys[i].PublicKey().Marshal(),
WithdrawalCredentials: make([]byte, 32),
}
}
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
require.NoError(t, err)
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := testutil.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
})
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
// In this test, att1 is from the prior fork and att2 is from the new fork.
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)
@@ -772,15 +719,11 @@ func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
b := testutil.NewBeaconBlock()
b.Block.Body.Attestations = []*ethpb.Attestation{att1, att2}
require.NoError(t, blocks.VerifyAttestationsSignatures(ctx, st, b))
}
func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing.T) {
ctx := context.Background()
numOfValidators := 4 * params.BeaconConfig().SlotsPerEpoch
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
validators := make([]*ethpb.Validator, numOfValidators)
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
require.NoError(t, err)

View File

@@ -5,10 +5,11 @@ import (
"sort"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/slashutil"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
@@ -35,11 +36,11 @@ import (
// assert slashed_any
func ProcessAttesterSlashings(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
@@ -54,14 +55,14 @@ func ProcessAttesterSlashings(
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
var err error
var slashedAny bool
var val stateTrie.ReadOnlyValidator
var val iface.ReadOnlyValidator
for _, validatorIndex := range slashableIndices {
val, err = beaconState.ValidatorAtIndexReadOnly(validatorIndex)
val, err = beaconState.ValidatorAtIndexReadOnly(types.ValidatorIndex(validatorIndex))
if err != nil {
return nil, err
}
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
beaconState, err = v.SlashValidator(beaconState, validatorIndex)
beaconState, err = v.SlashValidator(beaconState, types.ValidatorIndex(validatorIndex))
if err != nil {
return nil, errors.Wrapf(err, "could not slash validator index %d",
validatorIndex)
@@ -77,7 +78,7 @@ func ProcessAttesterSlashings(
}
// VerifyAttesterSlashing validates the attestation data in both attestations in the slashing object.
func VerifyAttesterSlashing(ctx context.Context, beaconState *stateTrie.BeaconState, slashing *ethpb.AttesterSlashing) error {
func VerifyAttesterSlashing(ctx context.Context, beaconState iface.ReadOnlyBeaconState, slashing *ethpb.AttesterSlashing) error {
if slashing == nil {
return errors.New("nil slashing")
}

View File

@@ -4,10 +4,11 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -43,9 +44,9 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
})}}
var registry []*ethpb.Validator
currentSlot := uint64(0)
currentSlot := types.Slot(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
@@ -62,9 +63,9 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T) {
var registry []*ethpb.Validator
currentSlot := uint64(0)
currentSlot := types.Slot(0)
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
@@ -98,7 +99,7 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
for _, vv := range beaconState.Validators() {
vv.WithdrawableEpoch = 1 * params.BeaconConfig().SlotsPerEpoch
vv.WithdrawableEpoch = types.Epoch(params.BeaconConfig().SlotsPerEpoch)
}
att1 := testutil.HydrateIndexedAttestation(&ethpb.IndexedAttestation{

View File

@@ -5,8 +5,9 @@ import (
"testing"
fuzz "github.com/google/gofuzz"
types "github.com/prysmaticlabs/eth2-types"
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -21,7 +22,7 @@ func TestFuzzProcessAttestationNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(att)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessAttestationNoVerifySignature(ctx, s, att)
_ = err
@@ -37,7 +38,7 @@ func TestFuzzProcessBlockHeader_10000(t *testing.T) {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeader(context.Background(), s, block)
_ = err
@@ -71,7 +72,7 @@ func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
func TestFuzzProcessEth1DataInBlock_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
b := &eth.SignedBeaconBlock{}
state := &stateTrie.BeaconState{}
state := &stateV0.BeaconState{}
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
@@ -102,7 +103,7 @@ func TestFuzzEth1DataHasEnoughSupport_10000(t *testing.T) {
for i := 0; i < 100000; i++ {
fuzzer.Fuzz(eth1data)
fuzzer.Fuzz(&stateVotes)
s, err := stateTrie.InitializeFromProto(&pb.BeaconState{
s, err := stateV0.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: stateVotes,
})
require.NoError(t, err)
@@ -120,7 +121,7 @@ func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(block)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeaderNoVerify(s, block)
_ = err
@@ -135,7 +136,7 @@ func TestFuzzProcessRandao_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandao(context.Background(), s, b)
if err != nil && r != nil {
@@ -152,7 +153,7 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(blockBody)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandaoNoVerify(s, blockBody)
if err != nil && r != nil {
@@ -169,7 +170,7 @@ func TestFuzzProcessProposerSlashings_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessProposerSlashings(ctx, s, b)
if err != nil && r != nil {
@@ -185,7 +186,7 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(proposerSlashing)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyProposerSlashing(s, proposerSlashing)
_ = err
@@ -200,7 +201,7 @@ func TestFuzzProcessAttesterSlashings_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttesterSlashings(ctx, s, b)
if err != nil && r != nil {
@@ -217,7 +218,7 @@ func TestFuzzVerifyAttesterSlashing_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attesterSlashing)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttesterSlashing(ctx, s, attesterSlashing)
_ = err
@@ -254,7 +255,7 @@ func TestFuzzProcessAttestations_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestations(ctx, s, b)
if err != nil && r != nil {
@@ -271,7 +272,7 @@ func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, b)
if err != nil && r != nil {
@@ -288,7 +289,7 @@ func TestFuzzProcessAttestation_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestation(ctx, s, attestation)
if err != nil && r != nil {
@@ -305,7 +306,7 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(idxAttestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyIndexedAttestation(ctx, s, idxAttestation)
_ = err
@@ -320,7 +321,7 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
@@ -330,16 +331,18 @@ func TestFuzzVerifyAttestation_10000(t *testing.T) {
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &pb.BeaconState{}
b := &eth.SignedBeaconBlock{}
deposits := make([]*eth.Deposit, 100)
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
for i := range deposits {
fuzzer.Fuzz(deposits[i])
}
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposits(ctx, s, b)
r, err := ProcessDeposits(ctx, s, deposits)
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, deposits)
}
}
}
@@ -353,7 +356,7 @@ func TestFuzzProcessPreGenesisDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessPreGenesisDeposits(ctx, s, []*eth.Deposit{deposit})
if err != nil && r != nil {
@@ -370,7 +373,7 @@ func TestFuzzProcessDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessDeposit(s, deposit, true)
if err != nil && r != nil {
@@ -386,7 +389,7 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(deposit)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
err = verifyDeposit(s, deposit)
_ = err
@@ -401,7 +404,7 @@ func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(ctx, s, b)
if err != nil && r != nil {
@@ -417,7 +420,7 @@ func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(b)
s, err := stateTrie.InitializeFromProtoUnsafe(state)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessVoluntaryExits(context.Background(), s, b)
if err != nil && r != nil {
@@ -429,9 +432,9 @@ func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
func TestFuzzVerifyExit_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
ve := &eth.SignedVoluntaryExit{}
val := stateTrie.ReadOnlyValidator{}
val := stateV0.ReadOnlyValidator{}
fork := &pb.Fork{}
var slot uint64
var slot types.Slot
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(ve)

View File

@@ -4,6 +4,7 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
@@ -18,7 +19,7 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
testutil.ResetCache()
beaconState, privKeys := testutil.DeterministicGenesisState(t, 5500)
for _, vv := range beaconState.Validators() {
vv.WithdrawableEpoch = 1 * params.BeaconConfig().SlotsPerEpoch
vv.WithdrawableEpoch = types.Epoch(params.BeaconConfig().SlotsPerEpoch)
}
// This set of indices is very similar to the one from our sapphire testnet
// when close to 100 validators were incorrectly slashed. The set is from 0 -5500,

View File

@@ -7,7 +7,7 @@ import (
"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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -20,15 +20,23 @@ import (
// ProcessPreGenesisDeposits processes a deposit for the beacon state before chainstart.
func ProcessPreGenesisDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
deposits []*ethpb.Deposit,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
var err error
beaconState, err = ProcessDeposits(ctx, beaconState, &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{Deposits: deposits}}})
beaconState, err = ProcessDeposits(ctx, beaconState, deposits)
if err != nil {
return nil, errors.Wrap(err, "could not process deposit")
}
beaconState, err = activateValidatorWithEffectiveBalance(beaconState, deposits)
if err != nil {
return nil, err
}
return beaconState, nil
}
// This updates validator's effective balance, and if it's above MaxEffectiveBalance, validator becomes active in genesis.
func activateValidatorWithEffectiveBalance(beaconState iface.BeaconState, deposits []*ethpb.Deposit) (iface.BeaconState, error) {
for _, deposit := range deposits {
pubkey := deposit.Data.PublicKey
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubkey))
@@ -67,33 +75,21 @@ func ProcessPreGenesisDeposits(
// process_deposit(state, deposit)
func ProcessDeposits(
ctx context.Context,
beaconState *stateTrie.BeaconState,
b *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
if b.Block == nil || b.Block.Body == nil {
return nil, errors.New("block and block body can't be nil")
}
deposits := b.Block.Body.Deposits
var err error
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return nil, err
}
beaconState iface.BeaconState,
deposits []*ethpb.Deposit,
) (iface.BeaconState, error) {
// Attempt to verify all deposit signatures at once, if this fails then fall back to processing
// individual deposits with signature verification enabled.
var verifySignature bool
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
log.WithError(err).Debug("Failed to verify deposit data, verifying signatures individually")
verifySignature = true
batchVerified, err := batchVerifyDepositsSignatures(ctx, deposits)
if err != nil {
return nil, err
}
for _, deposit := range deposits {
if deposit == nil || deposit.Data == nil {
return nil, errors.New("got a nil deposit in block")
}
beaconState, err = ProcessDeposit(beaconState, deposit, verifySignature)
beaconState, err = ProcessDeposit(beaconState, deposit, batchVerified)
if err != nil {
return nil, errors.Wrapf(err, "could not process deposit from %#x", bytesutil.Trunc(deposit.Data.PublicKey))
}
@@ -101,6 +97,21 @@ func ProcessDeposits(
return beaconState, nil
}
func batchVerifyDepositsSignatures(ctx context.Context, deposits []*ethpb.Deposit) (bool, error) {
var err error
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
if err != nil {
return false, err
}
verified := false
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
log.WithError(err).Debug("Failed to batch verify deposits signatures, will try individual verify")
verified = true
}
return verified, nil
}
// ProcessDeposit takes in a deposit object and inserts it
// into the registry as a new validator or balance change.
//
@@ -140,7 +151,7 @@ func ProcessDeposits(
// # Increase balance by deposit amount
// index = ValidatorIndex(validator_pubkeys.index(pubkey))
// increase_balance(state, index, amount)
func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (*stateTrie.BeaconState, error) {
func ProcessDeposit(beaconState iface.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (iface.BeaconState, error) {
if err := verifyDeposit(beaconState, deposit); err != nil {
if deposit == nil || deposit.Data == nil {
return nil, err
@@ -191,7 +202,7 @@ func ProcessDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit,
return beaconState, nil
}
func verifyDeposit(beaconState *stateTrie.BeaconState, deposit *ethpb.Deposit) error {
func verifyDeposit(beaconState iface.ReadOnlyBeaconState, deposit *ethpb.Deposit) error {
// Verify Merkle proof of deposit and deposit trie root.
if deposit == nil || deposit.Data == nil {
return errors.New("received nil deposit or nil deposit data")

View File

@@ -4,10 +4,11 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -39,7 +40,7 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -49,7 +50,7 @@ func TestProcessDeposits_SameValidatorMultipleDepositsSameBlock(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Expected block deposits to process correctly")
assert.Equal(t, 2, len(newState.Validators()), "Incorrect validator count")
@@ -79,7 +80,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
Deposits: []*ethpb.Deposit{deposit},
},
}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Eth1Data: &ethpb.Eth1Data{
DepositRoot: []byte{0},
BlockHash: []byte{1},
@@ -87,7 +88,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
})
require.NoError(t, err)
want := "deposit root did not verify"
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b)
_, err = blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
assert.ErrorContains(t, want, err)
}
@@ -110,7 +111,7 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -120,7 +121,7 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) {
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Expected block deposits to process correctly")
if newState.Balances()[1] != dep[0].Data.Amount {
t.Errorf(
@@ -173,7 +174,7 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
}
balances := []uint64{0, 50}
root := depositTrie.Root()
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: &ethpb.Eth1Data{
@@ -182,7 +183,7 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
},
})
require.NoError(t, err)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b)
newState, err := blocks.ProcessDeposits(context.Background(), beaconState, b.Block.Body.Deposits)
require.NoError(t, err, "Process deposit failed")
assert.Equal(t, uint64(1000+50), newState.Balances()[1], "Expected balance at index 1 to be 1050")
}
@@ -201,7 +202,7 @@ func TestProcessDeposit_AddsNewValidatorDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -243,7 +244,7 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -299,7 +300,7 @@ func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
},
}
balances := []uint64{0}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Balances: balances,
Eth1Data: eth1Data,
@@ -316,11 +317,11 @@ func TestPreGenesisDeposits_SkipInvalidDeposit(t *testing.T) {
require.Equal(t, false, ok, "bad pubkey should not exist in state")
for i := 1; i < newState.NumValidators(); i++ {
val, err := newState.ValidatorAtIndex(uint64(i))
val, err := newState.ValidatorAtIndex(types.ValidatorIndex(i))
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalance, val.EffectiveBalance, "unequal effective balance")
require.Equal(t, uint64(0), val.ActivationEpoch)
require.Equal(t, uint64(0), val.ActivationEligibilityEpoch)
require.Equal(t, types.Epoch(0), val.ActivationEpoch)
require.Equal(t, types.Epoch(0), val.ActivationEligibilityEpoch)
}
if newState.Eth1DepositIndex() != 100 {
t.Errorf(

View File

@@ -6,7 +6,8 @@ import (
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -19,7 +20,7 @@ import (
// state.eth1_data_votes.append(body.eth1_data)
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
// state.latest_eth1_data = body.eth1_data
func ProcessEth1DataInBlock(_ context.Context, beaconState *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) (*stateTrie.BeaconState, error) {
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, b *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
block := b.Block
if beaconState == nil {
return nil, errors.New("nil state")
@@ -59,9 +60,9 @@ func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
// eth1 voting period. A vote is cast by including eth1data in a block and part of state processing
// appends eth1data to the state in the Eth1DataVotes list. Iterating through this list checks the
// votes to see if they match the eth1data.
func Eth1DataHasEnoughSupport(beaconState *stateTrie.BeaconState, data *ethpb.Eth1Data) (bool, error) {
func Eth1DataHasEnoughSupport(beaconState iface.ReadOnlyBeaconState, data *ethpb.Eth1Data) (bool, error) {
voteCount := uint64(0)
data = stateTrie.CopyETH1Data(data)
data = stateV0.CopyETH1Data(data)
for _, vote := range beaconState.Eth1DataVotes() {
if AreEth1DataEqual(vote, data) {
@@ -71,6 +72,6 @@ func Eth1DataHasEnoughSupport(beaconState *stateTrie.BeaconState, data *ethpb.Et
// If 50+% majority converged on the same eth1data, then it has enough support to update the
// state.
support := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
return voteCount*2 > support, nil
support := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))
return voteCount*2 > uint64(support), nil
}

View File

@@ -6,9 +6,10 @@ import (
"testing"
"github.com/gogo/protobuf/proto"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -33,10 +34,10 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
stateVotes []*ethpb.Eth1Data
data *ethpb.Eth1Data
hasSupport bool
votingPeriodLength uint64
votingPeriodLength types.Epoch
}{
{
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -44,7 +45,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
hasSupport: true,
votingPeriodLength: 7,
}, {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -52,7 +53,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
hasSupport: false,
votingPeriodLength: 8,
}, {
stateVotes: FakeDeposits(4 * params.BeaconConfig().SlotsPerEpoch),
stateVotes: FakeDeposits(uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))),
data: &ethpb.Eth1Data{
DepositCount: 1,
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
@@ -69,7 +70,7 @@ func TestEth1DataHasEnoughSupport(t *testing.T) {
c.EpochsPerEth1VotingPeriod = tt.votingPeriodLength
params.OverrideBeaconConfig(c)
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
s, err := stateV0.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: tt.stateVotes,
})
require.NoError(t, err)
@@ -159,7 +160,7 @@ func TestAreEth1DataEqual(t *testing.T) {
}
func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
beaconState, err := beaconstate.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Eth1DataVotes: []*ethpb.Eth1Data{},
})
require.NoError(t, err)
@@ -174,17 +175,20 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
},
}
period := params.BeaconConfig().EpochsPerEth1VotingPeriod * params.BeaconConfig().SlotsPerEpoch
period := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod)))
var ok bool
for i := uint64(0); i < period; i++ {
beaconState, err = blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
processedState, err := blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
require.NoError(t, err)
beaconState, ok = processedState.(*stateV0.BeaconState)
require.Equal(t, true, ok)
}
newETH1DataVotes := beaconState.Eth1DataVotes()
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), beaconstate.CopyETH1Data(b.Block.Body.Eth1Data)) {
if !proto.Equal(beaconState.Eth1Data(), stateV0.CopyETH1Data(b.Block.Body.Eth1Data)) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
b.Block.Body.Eth1Data,

View File

@@ -5,10 +5,11 @@ import (
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -25,31 +26,30 @@ var ValidatorCannotExitYetMsg = "validator has not been active long enough to ex
// should exit the state's validator registry.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, exit.validator_index)
// initiate_validator_exit(state, voluntary_exit.validator_index)
func ProcessVoluntaryExits(
_ context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
@@ -73,59 +73,33 @@ func ProcessVoluntaryExits(
return beaconState, nil
}
// ProcessVoluntaryExitsNoVerifySignature processes all the voluntary exits in
// a block body, without verifying their BLS signatures.
// This function is here to satisfy fuzz tests.
func ProcessVoluntaryExitsNoVerifySignature(
beaconState *stateTrie.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
exits := body.VoluntaryExits
for idx, exit := range exits {
if exit == nil || exit.Exit == nil {
return nil, errors.New("nil exit")
}
val, err := beaconState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)
if err != nil {
return nil, err
}
if err := verifyExitConditions(val, beaconState.Slot(), exit.Exit); err != nil {
return nil, err
}
// Validate that fork and genesis root are valid.
_, err = helpers.Domain(beaconState.Fork(), exit.Exit.Epoch, params.BeaconConfig().DomainVoluntaryExit, beaconState.GenesisValidatorRoot())
if err != nil {
return nil, err
}
beaconState, err = v.InitiateValidatorExit(beaconState, exit.Exit.ValidatorIndex)
if err != nil {
return nil, errors.Wrapf(err, "failed to process voluntary exit at index %d", idx)
}
}
return beaconState, nil
}
// VerifyExitAndSignature implements the spec defined validation for voluntary exits.
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
func VerifyExitAndSignature(validator stateTrie.ReadOnlyValidator, currentSlot uint64, fork *pb.Fork, signed *ethpb.SignedVoluntaryExit, genesisRoot []byte) error {
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, voluntary_exit.validator_index)
func VerifyExitAndSignature(
validator iface.ReadOnlyValidator,
currentSlot types.Slot,
fork *pb.Fork,
signed *ethpb.SignedVoluntaryExit,
genesisRoot []byte,
) error {
if signed == nil || signed.Exit == nil {
return errors.New("nil exit")
}
@@ -148,20 +122,24 @@ func VerifyExitAndSignature(validator stateTrie.ReadOnlyValidator, currentSlot u
// verifyExitConditions implements the spec defined validation for voluntary exits(excluding signatures).
//
// Spec pseudocode definition:
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
// """
// Process ``VoluntaryExit`` operation.
// """
// validator = state.validator_registry[exit.validator_index]
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
// voluntary_exit = signed_voluntary_exit.message
// validator = state.validators[voluntary_exit.validator_index]
// # Verify the validator is active
// assert is_active_validator(validator, get_current_epoch(state))
// # Verify the validator has not yet exited
// # Verify exit has not been initiated
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
// # Exits must specify an epoch when they become valid; they are not valid before then
// assert get_current_epoch(state) >= exit.epoch
// assert get_current_epoch(state) >= voluntary_exit.epoch
// # Verify the validator has been active long enough
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
func verifyExitConditions(validator stateTrie.ReadOnlyValidator, currentSlot uint64, exit *ethpb.VoluntaryExit) error {
// # Verify signature
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
// signing_root = compute_signing_root(voluntary_exit, domain)
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
// # Initiate exit
// initiate_validator_exit(state, voluntary_exit.validator_index)
func verifyExitConditions(validator iface.ReadOnlyValidator, currentSlot types.Slot, exit *ethpb.VoluntaryExit) error {
currentEpoch := helpers.SlotToEpoch(currentSlot)
// Verify the validator is active.
if !helpers.IsActiveValidatorUsingTrie(validator, currentEpoch) {
@@ -178,9 +156,10 @@ func verifyExitConditions(validator stateTrie.ReadOnlyValidator, currentSlot uin
// Verify the validator has been active long enough.
if currentEpoch < validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod {
return fmt.Errorf(
"%s: %d epochs vs required %d epochs",
"%s: %d of %d epochs. Validator will be eligible for exit at epoch %d",
ValidatorCannotExitYetMsg,
currentEpoch,
currentEpoch-validator.ActivationEpoch(),
params.BeaconConfig().ShardCommitteePeriod,
validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod,
)
}

View File

@@ -4,10 +4,11 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -16,73 +17,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestProcessVoluntaryExits_ValidatorNotActive(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 0,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "non-active validator cannot exit"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_InvalidExitEpoch(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 10,
},
},
}
registry := []*ethpb.Validator{
{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 0,
})
require.NoError(t, err)
b := testutil.NewBeaconBlock()
b.Block = &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
want := "expected current epoch >= exit epoch"
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
assert.ErrorContains(t, want, err)
// Check conformance of no verify method.
_, err = blocks.ProcessVoluntaryExitsNoVerifySignature(state, b.Block.Body)
assert.ErrorContains(t, want, err)
}
func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{
@@ -97,7 +31,7 @@ func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 10,
})
@@ -127,7 +61,7 @@ func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) {
ExitEpoch: 10,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: 0,
})
@@ -159,7 +93,7 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
ActivationEpoch: 0,
},
}
state, err := stateTrie.InitializeFromProto(&pb.BeaconState{
state, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Fork: &pb.Fork{
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
@@ -168,7 +102,7 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
Slot: params.BeaconConfig().SlotsPerEpoch * 5,
})
require.NoError(t, err)
err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch))
err = state.SetSlot(state.Slot() + params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)))
require.NoError(t, err)
priv, err := bls.RandKey()
@@ -188,21 +122,11 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
},
}
stateCopy := state.Copy()
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b)
require.NoError(t, err, "Could not process exits")
newRegistry := newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch) {
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
}
// Check conformance with NoVerify Exit Method.
newState, err = blocks.ProcessVoluntaryExitsNoVerifySignature(stateCopy, b.Block.Body)
require.NoError(t, err, "Could not process exits")
newRegistry = newState.Validators()
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch) {
t.Errorf("Expected validator exit epoch to be %d, got %d",
helpers.ActivationExitEpoch(stateCopy.Slot()/params.BeaconConfig().SlotsPerEpoch), newRegistry[0].ExitEpoch)
helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)), newRegistry[0].ExitEpoch)
}
}

View File

@@ -8,7 +8,7 @@ import (
"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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -38,9 +38,9 @@ import (
// assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
func ProcessBlockHeader(
_ context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
block *ethpb.SignedBeaconBlock,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
beaconState, err := ProcessBlockHeaderNoVerify(beaconState, block.Block)
if err != nil {
return nil, err
@@ -80,9 +80,9 @@ func ProcessBlockHeader(
// proposer = state.validators[get_beacon_proposer_index(state)]
// assert not proposer.slashed
func ProcessBlockHeaderNoVerify(
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
block *ethpb.BeaconBlock,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
if block == nil {
return nil, errors.New("nil block")
}

View File

@@ -4,14 +4,13 @@ import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessProposerSlashings is one of the operations performed
@@ -38,11 +37,11 @@ import (
// slash_validator(state, proposer_slashing.proposer_index)
func ProcessProposerSlashings(
_ context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
@@ -66,7 +65,7 @@ func ProcessProposerSlashings(
// VerifyProposerSlashing verifies that the data provided from slashing is valid.
func VerifyProposerSlashing(
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
slashing *ethpb.ProposerSlashing,
) error {
if slashing.Header_1 == nil || slashing.Header_1.Header == nil || slashing.Header_2 == nil || slashing.Header_2.Header == nil {

View File

@@ -5,9 +5,9 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -24,7 +24,7 @@ func TestVerifyProposerSlashing_BeaconFuzzIssue91(t *testing.T) {
err = rawState.UnmarshalSSZ(file)
require.NoError(t, err)
st, err := stateTrie.InitializeFromProtoUnsafe(rawState)
st, err := stateV0.InitializeFromProtoUnsafe(rawState)
require.NoError(t, err)
file, err = ioutil.ReadFile("testdata/beaconfuzz_91_proposer_slashing.ssz")

View File

@@ -5,10 +5,12 @@ import (
"fmt"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
@@ -21,7 +23,7 @@ import (
func TestProcessProposerSlashings_UnmatchedHeaderSlots(t *testing.T) {
testutil.ResetCache()
beaconState, _ := testutil.DeterministicGenesisState(t, 20)
currentSlot := uint64(0)
currentSlot := types.Slot(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
@@ -54,7 +56,7 @@ func TestProcessProposerSlashings_UnmatchedHeaderSlots(t *testing.T) {
func TestProcessProposerSlashings_SameHeaders(t *testing.T) {
testutil.ResetCache()
beaconState, _ := testutil.DeterministicGenesisState(t, 2)
currentSlot := uint64(0)
currentSlot := types.Slot(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
@@ -93,7 +95,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
WithdrawableEpoch: 0,
},
}
currentSlot := uint64(0)
currentSlot := types.Slot(0)
slashings := []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
@@ -115,7 +117,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
},
}
beaconState, err := stateTrie.InitializeFromProto(&pb.BeaconState{
beaconState, err := stateV0.InitializeFromProto(&pb.BeaconState{
Validators: registry,
Slot: currentSlot,
})
@@ -138,7 +140,7 @@ 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)
proposerIdx := types.ValidatorIndex(1)
header1 := &ethpb.SignedBeaconBlockHeader{
Header: testutil.HydrateBeaconHeader(&ethpb.BeaconBlockHeader{
@@ -181,12 +183,12 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
func TestVerifyProposerSlashing(t *testing.T) {
type args struct {
beaconState *stateTrie.BeaconState
beaconState iface.BeaconState
slashing *ethpb.ProposerSlashing
}
beaconState, sks := testutil.DeterministicGenesisState(t, 2)
currentSlot := uint64(0)
currentSlot := types.Slot(0)
require.NoError(t, beaconState.SetSlot(currentSlot))
rand1, err := bls.RandKey()
require.NoError(t, err)

View File

@@ -6,7 +6,7 @@ import (
"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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -27,13 +27,12 @@ import (
// state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
func ProcessRandao(
_ context.Context,
beaconState *stateTrie.BeaconState,
beaconState iface.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")
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
buf, proposerPub, domain, err := randaoSigningData(beaconState)
if err != nil {
@@ -60,14 +59,14 @@ func ProcessRandao(
// hash(body.randao_reveal))
// )
func ProcessRandaoNoVerify(
beaconState *stateTrie.BeaconState,
beaconState iface.BeaconState,
body *ethpb.BeaconBlockBody,
) (*stateTrie.BeaconState, error) {
) (iface.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)
latestMixSlice, err := beaconState.RandaoMixAtIndex(uint64(currentEpoch % latestMixesLength))
if err != nil {
return nil, err
}
@@ -78,7 +77,7 @@ func ProcessRandaoNoVerify(
for i, x := range blockRandaoReveal {
latestMixSlice[i] ^= x
}
if err := beaconState.UpdateRandaoMixesAtIndex(currentEpoch%latestMixesLength, latestMixSlice); err != nil {
if err := beaconState.UpdateRandaoMixesAtIndex(uint64(currentEpoch%latestMixesLength), latestMixSlice); err != nil {
return nil, err
}
return beaconState, nil

View File

@@ -5,6 +5,7 @@ import (
"encoding/binary"
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
@@ -20,9 +21,9 @@ func TestProcessRandao_IncorrectProposerFailsVerification(t *testing.T) {
// 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)
epoch := types.Epoch(0)
buf := make([]byte, 32)
binary.LittleEndian.PutUint64(buf, epoch)
binary.LittleEndian.PutUint64(buf, uint64(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()

View File

@@ -5,9 +5,10 @@ import (
"encoding/binary"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
@@ -59,7 +60,7 @@ func verifySignature(signedData, pub, signature, domain []byte) error {
}
// VerifyBlockSignature verifies the proposer signature of a beacon block.
func VerifyBlockSignature(beaconState *stateTrie.BeaconState, block *ethpb.SignedBeaconBlock) error {
func VerifyBlockSignature(beaconState iface.ReadOnlyBeaconState, block *ethpb.SignedBeaconBlock) error {
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconProposer, beaconState.GenesisValidatorRoot())
if err != nil {
@@ -74,7 +75,7 @@ func VerifyBlockSignature(beaconState *stateTrie.BeaconState, block *ethpb.Signe
}
// 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) {
func BlockSignatureSet(beaconState iface.ReadOnlyBeaconState, 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 {
@@ -90,7 +91,7 @@ func BlockSignatureSet(beaconState *stateTrie.BeaconState, block *ethpb.SignedBe
// RandaoSignatureSet retrieves the relevant randao specific signature set object
// from a block and its corresponding state.
func RandaoSignatureSet(beaconState *stateTrie.BeaconState,
func RandaoSignatureSet(beaconState iface.ReadOnlyBeaconState,
body *ethpb.BeaconBlockBody,
) (*bls.SignatureSet, error) {
buf, proposerPub, domain, err := randaoSigningData(beaconState)
@@ -105,7 +106,7 @@ func RandaoSignatureSet(beaconState *stateTrie.BeaconState,
}
// retrieves the randao related signing data from the state.
func randaoSigningData(beaconState *stateTrie.BeaconState) ([]byte, []byte, []byte, error) {
func randaoSigningData(beaconState iface.ReadOnlyBeaconState) ([]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")
@@ -114,7 +115,7 @@ func randaoSigningData(beaconState *stateTrie.BeaconState) ([]byte, []byte, []by
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
buf := make([]byte, 32)
binary.LittleEndian.PutUint64(buf, currentEpoch)
binary.LittleEndian.PutUint64(buf, uint64(currentEpoch))
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainRandao, beaconState.GenesisValidatorRoot())
if err != nil {
@@ -124,7 +125,12 @@ func randaoSigningData(beaconState *stateTrie.BeaconState) ([]byte, []byte, []by
}
// 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) {
func createAttestationSignatureSet(
ctx context.Context,
beaconState iface.ReadOnlyBeaconState,
atts []*ethpb.Attestation,
domain []byte,
) (*bls.SignatureSet, error) {
if len(atts) == 0 {
return nil, nil
}
@@ -148,7 +154,7 @@ func createAttestationSignatureSet(ctx context.Context, beaconState *stateTrie.B
indices := ia.AttestingIndices
pubkeys := make([][]byte, len(indices))
for i := 0; i < len(indices); i++ {
pubkeyAtIdx := beaconState.PubkeyAtIndex(indices[i])
pubkeyAtIdx := beaconState.PubkeyAtIndex(types.ValidatorIndex(indices[i]))
pubkeys[i] = pubkeyAtIdx[:]
}
aggP, err := bls.AggregatePublicKeys(pubkeys)
@@ -172,7 +178,7 @@ func createAttestationSignatureSet(ctx context.Context, beaconState *stateTrie.B
// 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) {
func AttestationSignatureSet(ctx context.Context, beaconState iface.ReadOnlyBeaconState, atts []*ethpb.Attestation) (*bls.SignatureSet, error) {
if len(atts) == 0 {
return bls.NewSet(), nil
}

View File

@@ -36,7 +36,8 @@ go_test(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/core/state/stateutils:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",
@@ -71,7 +72,8 @@ go_test(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/core/state/stateutils:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",

View File

@@ -10,7 +10,7 @@ import (
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -33,7 +33,7 @@ func runBlockHeaderTest(t *testing.T, config string) {
require.NoError(t, err)
preBeaconStateBase := &pb.BeaconState{}
require.NoError(t, preBeaconStateBase.UnmarshalSSZ(preBeaconStateFile), "Failed to unmarshal")
preBeaconState, err := stateTrie.InitializeFromProto(preBeaconStateBase)
preBeaconState, err := stateV0.InitializeFromProto(preBeaconStateBase)
require.NoError(t, err)
// If the post.ssz is not present, it means the test should fail on our end.
@@ -55,7 +55,9 @@ func runBlockHeaderTest(t *testing.T, config string) {
postBeaconState := &pb.BeaconState{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateFile), "Failed to unmarshal")
if !proto.Equal(beaconState.CloneInnerState(), postBeaconState) {
pbState, err := stateV0.ProtobufBeaconState(beaconState.CloneInnerState())
require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.CloneInnerState(), postBeaconState)
t.Log(diff)
t.Fatal("Post state does not match expected")

View File

@@ -15,7 +15,8 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -38,7 +39,7 @@ func runBlockProcessingTest(t *testing.T, config string) {
require.NoError(t, err)
beaconStateBase := &pb.BeaconState{}
require.NoError(t, beaconStateBase.UnmarshalSSZ(preBeaconStateFile), "Failed to unmarshal")
beaconState, err := stateTrie.InitializeFromProto(beaconStateBase)
beaconState, err := stateV0.InitializeFromProto(beaconStateBase)
require.NoError(t, err)
file, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "meta.yaml")
@@ -48,16 +49,20 @@ func runBlockProcessingTest(t *testing.T, config string) {
require.NoError(t, testutil.UnmarshalYaml(file, metaYaml), "Failed to Unmarshal")
var transitionError error
var processedState iface.BeaconState
var ok bool
for i := 0; i < metaYaml.BlocksCount; i++ {
filename := fmt.Sprintf("blocks_%d.ssz", i)
blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), filename)
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{}
require.NoError(t, block.UnmarshalSSZ(blockFile), "Failed to unmarshal")
beaconState, transitionError = state.ExecuteStateTransition(context.Background(), beaconState, block)
processedState, transitionError = state.ExecuteStateTransition(context.Background(), beaconState, block)
if transitionError != nil {
break
}
beaconState, ok = processedState.(*stateV0.BeaconState)
require.Equal(t, true, ok)
}
// If the post.ssz is not present, it means the test should fail on our end.
@@ -79,8 +84,9 @@ func runBlockProcessingTest(t *testing.T, config string) {
postBeaconState := &pb.BeaconState{}
require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateFile), "Failed to unmarshal")
if !proto.Equal(beaconState.InnerStateUnsafe(), postBeaconState) {
pbState, err := stateV0.ProtobufBeaconState(beaconState.InnerStateUnsafe())
require.NoError(t, err)
if !proto.Equal(pbState, postBeaconState) {
diff, _ := messagediff.PrettyDiff(beaconState.InnerStateUnsafe(), postBeaconState)
t.Log(diff)
t.Fatal("Post state does not match expected")

View File

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

View File

@@ -9,12 +9,14 @@ go_library(
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
],
)
@@ -29,7 +31,8 @@ go_test(
embed = [":go_default_library"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
@@ -37,6 +40,7 @@ go_test(
"//shared/testutil/require:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
],

View File

@@ -9,10 +9,12 @@ import (
"sort"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/mathutil"
@@ -22,7 +24,7 @@ import (
// sortableIndices implements the Sort interface to sort newly activated validator indices
// by activation epoch and by index number.
type sortableIndices struct {
indices []uint64
indices []types.ValidatorIndex
validators []*ethpb.Validator
}
@@ -42,9 +44,13 @@ func (s sortableIndices) Less(i, j int) bool {
// need to get attesting balance from attestations.
//
// Spec pseudocode definition:
// def get_attesting_balance(state: BeaconState, attestations: List[PendingAttestation]) -> Gwei:
// def get_attesting_balance(state: BeaconState, attestations: Sequence[PendingAttestation]) -> Gwei:
// """
// Return the combined effective balance of the set of unslashed validators participating in ``attestations``.
// Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
// """
// return get_total_balance(state, get_unslashed_attesting_indices(state, attestations))
func AttestingBalance(state *stateTrie.BeaconState, atts []*pb.PendingAttestation) (uint64, error) {
func AttestingBalance(state iface.ReadOnlyBeaconState, atts []*pb.PendingAttestation) (uint64, error) {
indices, err := UnslashedAttestingIndices(state, atts)
if err != nil {
return 0, errors.Wrap(err, "could not get attesting indices")
@@ -75,7 +81,7 @@ func AttestingBalance(state *stateTrie.BeaconState, atts []*pb.PendingAttestatio
// for index in activation_queue[:get_validator_churn_limit(state)]:
// validator = state.validators[index]
// validator.activation_epoch = compute_activation_exit_epoch(get_current_epoch(state))
func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState, error) {
func ProcessRegistryUpdates(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
vals := state.Validators()
var err error
@@ -85,7 +91,7 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat
// Process the validators for activation eligibility.
if helpers.IsEligibleForActivationQueue(validator) {
validator.ActivationEligibilityEpoch = activationEligibilityEpoch
if err := state.UpdateValidatorAtIndex(uint64(idx), validator); err != nil {
if err := state.UpdateValidatorAtIndex(types.ValidatorIndex(idx), validator); err != nil {
return nil, err
}
}
@@ -94,7 +100,7 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat
isActive := helpers.IsActiveValidator(validator, currentEpoch)
belowEjectionBalance := validator.EffectiveBalance <= ejectionBal
if isActive && belowEjectionBalance {
state, err = validators.InitiateValidatorExit(state, uint64(idx))
state, err = validators.InitiateValidatorExit(state, types.ValidatorIndex(idx))
if err != nil {
return nil, errors.Wrapf(err, "could not initiate exit for validator %d", idx)
}
@@ -102,10 +108,10 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat
}
// Queue validators eligible for activation and not yet dequeued for activation.
var activationQ []uint64
var activationQ []types.ValidatorIndex
for idx, validator := range vals {
if helpers.IsEligibleForActivation(state, validator) {
activationQ = append(activationQ, uint64(idx))
activationQ = append(activationQ, types.ValidatorIndex(idx))
}
}
@@ -154,7 +160,7 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat
// 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) {
func ProcessSlashings(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
totalBalance, err := helpers.TotalActiveBalance(state)
if err != nil {
@@ -175,62 +181,30 @@ func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, err
// 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) {
err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / totalBalance * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
return false, err
if err := helpers.DecreaseBalance(state, types.ValidatorIndex(idx), penalty); err != nil {
return false, val, err
}
return true, nil
return true, val, nil
}
return false, nil
return false, val, nil
})
return state, err
}
// ProcessFinalUpdates processes the final updates during epoch processing.
// ProcessEth1DataReset processes updates to ETH1 data votes during epoch processing.
//
// Spec pseudocode definition:
// def process_final_updates(state: BeaconState) -> None:
// current_epoch = get_current_epoch(state)
// next_epoch = Epoch(current_epoch + 1)
// def process_eth1_data_reset(state: BeaconState) -> None:
// next_epoch = Epoch(get_current_epoch(state) + 1)
// # Reset eth1 data votes
// if next_epoch % EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
// state.eth1_data_votes = []
// # Update effective balances with hysteresis
// for index, validator in enumerate(state.validators):
// balance = state.balances[index]
// HYSTERESIS_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT
// DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
// UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
// if (
// balance + DOWNWARD_THRESHOLD < validator.effective_balance
// or validator.effective_balance + UPWARD_THRESHOLD < balance
// ):
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
// index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY)
// index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR
// indices_list = List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, index_epoch))
// state.active_index_roots[index_root_position] = hash_tree_root(indices_list)
// # Set committees root
// committee_root_position = next_epoch % EPOCHS_PER_HISTORICAL_VECTOR
// state.compact_committees_roots[committee_root_position] = get_compact_committees_root(state, next_epoch)
// # Reset slashings
// state.slashings[next_epoch % EPOCHS_PER_SLASHINGS_VECTOR] = Gwei(0)
// # Set randao mix
// state.randao_mixes[next_epoch % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, current_epoch)
// # Set historical root accumulator
// if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0:
// historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots)
// state.historical_roots.append(hash_tree_root(historical_batch))
// # Update start shard
// state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT)
// # Rotate current/previous epoch attestations
// state.previous_epoch_attestations = state.current_epoch_attestations
// state.current_epoch_attestations = []
func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState, error) {
func ProcessEth1DataReset(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
nextEpoch := currentEpoch + 1
@@ -241,6 +215,25 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
}
}
return state, nil
}
// ProcessEffectiveBalanceUpdates processes effective balance updates during epoch processing.
//
// Spec pseudocode definition:
// def process_effective_balance_updates(state: BeaconState) -> None:
// # Update effective balances with hysteresis
// for index, validator in enumerate(state.validators):
// balance = state.balances[index]
// HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT)
// DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
// UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
// if (
// balance + DOWNWARD_THRESHOLD < validator.effective_balance
// or validator.effective_balance + UPWARD_THRESHOLD < balance
// ):
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
func ProcessEffectiveBalanceUpdates(state iface.BeaconState) (iface.BeaconState, error) {
effBalanceInc := params.BeaconConfig().EffectiveBalanceIncrement
maxEffBalance := params.BeaconConfig().MaxEffectiveBalance
hysteresisInc := effBalanceInc / params.BeaconConfig().HysteresisQuotient
@@ -249,47 +242,77 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
bals := state.Balances()
// Update effective balances with hysteresis.
validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
validatorFunc := func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
if val == nil {
return false, fmt.Errorf("validator %d is nil in state", idx)
return false, nil, fmt.Errorf("validator %d is nil in state", idx)
}
if idx >= len(bals) {
return false, fmt.Errorf("validator index exceeds validator length in state %d >= %d", idx, len(state.Balances()))
return false, nil, fmt.Errorf("validator index exceeds validator length in state %d >= %d", idx, len(state.Balances()))
}
balance := bals[idx]
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
val.EffectiveBalance = maxEffBalance
if val.EffectiveBalance > balance-balance%effBalanceInc {
val.EffectiveBalance = balance - balance%effBalanceInc
newVal := stateV0.CopyValidator(val)
newVal.EffectiveBalance = maxEffBalance
if newVal.EffectiveBalance > balance-balance%effBalanceInc {
newVal.EffectiveBalance = balance - balance%effBalanceInc
}
return true, nil
return true, newVal, nil
}
return false, nil
return false, val, nil
}
if err := state.ApplyToEveryValidator(validatorFunc); err != nil {
return nil, err
}
return state, nil
}
// ProcessSlashingsReset processes the total slashing balances updates during epoch processing.
//
// Spec pseudocode definition:
// def process_slashings_reset(state: BeaconState) -> None:
// next_epoch = Epoch(get_current_epoch(state) + 1)
// # Reset slashings
// state.slashings[next_epoch % EPOCHS_PER_SLASHINGS_VECTOR] = Gwei(0)
func ProcessSlashingsReset(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
nextEpoch := currentEpoch + 1
// Set total slashed balances.
slashedExitLength := params.BeaconConfig().EpochsPerSlashingsVector
slashedEpoch := nextEpoch % slashedExitLength
slashings := state.Slashings()
if uint64(len(slashings)) != slashedExitLength {
if uint64(len(slashings)) != uint64(slashedExitLength) {
return nil, fmt.Errorf(
"state slashing length %d different than EpochsPerHistoricalVector %d",
len(slashings),
slashedExitLength,
)
}
if err := state.UpdateSlashingsAtIndex(slashedEpoch /* index */, 0 /* value */); err != nil {
if err := state.UpdateSlashingsAtIndex(uint64(slashedEpoch) /* index */, 0 /* value */); err != nil {
return nil, err
}
return state, nil
}
// ProcessRandaoMixesReset processes the final updates to RANDAO mix during epoch processing.
//
// Spec pseudocode definition:
// def process_randao_mixes_reset(state: BeaconState) -> None:
// current_epoch = get_current_epoch(state)
// next_epoch = Epoch(current_epoch + 1)
// # Set randao mix
// state.randao_mixes[next_epoch % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, current_epoch)
func ProcessRandaoMixesReset(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
nextEpoch := currentEpoch + 1
// Set RANDAO mix.
randaoMixLength := params.BeaconConfig().EpochsPerHistoricalVector
if uint64(state.RandaoMixesLength()) != randaoMixLength {
if uint64(state.RandaoMixesLength()) != uint64(randaoMixLength) {
return nil, fmt.Errorf(
"state randao length %d different than EpochsPerHistoricalVector %d",
state.RandaoMixesLength(),
@@ -300,13 +323,29 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
if err != nil {
return nil, err
}
if err := state.UpdateRandaoMixesAtIndex(nextEpoch%randaoMixLength, mix); err != nil {
if err := state.UpdateRandaoMixesAtIndex(uint64(nextEpoch%randaoMixLength), mix); err != nil {
return nil, err
}
return state, nil
}
// ProcessHistoricalRootsUpdate processes the updates to historical root accumulator during epoch processing.
//
// Spec pseudocode definition:
// def process_historical_roots_update(state: BeaconState) -> None:
// # Set historical root accumulator
// next_epoch = Epoch(get_current_epoch(state) + 1)
// if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0:
// historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots)
// state.historical_roots.append(hash_tree_root(historical_batch))
func ProcessHistoricalRootsUpdate(state iface.BeaconState) (iface.BeaconState, error) {
currentEpoch := helpers.CurrentEpoch(state)
nextEpoch := currentEpoch + 1
// Set historical root accumulator.
epochsPerHistoricalRoot := params.BeaconConfig().SlotsPerHistoricalRoot / params.BeaconConfig().SlotsPerEpoch
if nextEpoch%epochsPerHistoricalRoot == 0 {
epochsPerHistoricalRoot := params.BeaconConfig().SlotsPerHistoricalRoot.DivSlot(params.BeaconConfig().SlotsPerEpoch)
if nextEpoch.Mod(uint64(epochsPerHistoricalRoot)) == 0 {
historicalBatch := &pb.HistoricalBatch{
BlockRoots: state.BlockRoots(),
StateRoots: state.StateRoots(),
@@ -320,13 +359,63 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
}
}
return state, nil
}
// ProcessParticipationRecordUpdates rotates current/previous epoch attestations during epoch processing.
//
// Spec pseudocode definition:
// def process_participation_record_updates(state: BeaconState) -> None:
// # Rotate current/previous epoch attestations
// state.previous_epoch_attestations = state.current_epoch_attestations
// state.current_epoch_attestations = []
func ProcessParticipationRecordUpdates(state iface.BeaconState) (iface.BeaconState, error) {
if err := state.RotateAttestations(); err != nil {
return nil, err
}
return state, nil
}
// ProcessFinalUpdates processes the final updates during epoch processing.
func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
var err error
// Reset ETH1 data votes.
state, err = ProcessEth1DataReset(state)
if err != nil {
return nil, err
}
// Update effective balances with hysteresis.
state, err = ProcessEffectiveBalanceUpdates(state)
if err != nil {
return nil, err
}
// Set total slashed balances.
state, err = ProcessSlashingsReset(state)
if err != nil {
return nil, err
}
// Set RANDAO mix.
state, err = ProcessRandaoMixesReset(state)
if err != nil {
return nil, err
}
// Set historical root accumulator.
state, err = ProcessHistoricalRootsUpdate(state)
if err != nil {
return nil, err
}
// Rotate current and previous epoch attestations.
if err := state.SetPreviousEpochAttestations(state.CurrentEpochAttestations()); err != nil {
return nil, err
}
if err := state.SetCurrentEpochAttestations([]*pb.PendingAttestation{}); err != nil {
state, err = ProcessParticipationRecordUpdates(state)
if err != nil {
return nil, err
}
return state, nil
}
@@ -340,8 +429,8 @@ 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) {
var setIndices []uint64
func UnslashedAttestingIndices(state iface.ReadOnlyBeaconState, atts []*pb.PendingAttestation) ([]types.ValidatorIndex, error) {
var setIndices []types.ValidatorIndex
seen := make(map[uint64]bool)
for _, att := range atts {
@@ -356,7 +445,7 @@ func UnslashedAttestingIndices(state *stateTrie.BeaconState, atts []*pb.PendingA
// Create a set for attesting indices
for _, index := range attestingIndices {
if !seen[index] {
setIndices = append(setIndices, index)
setIndices = append(setIndices, types.ValidatorIndex(index))
}
seen[index] = true
}
@@ -388,7 +477,7 @@ func UnslashedAttestingIndices(state *stateTrie.BeaconState, atts []*pb.PendingA
// total_balance = get_total_active_balance(state)
// effective_balance = state.validator_registry[index].effective_balance
// return effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH
func BaseReward(state *stateTrie.BeaconState, index uint64) (uint64, error) {
func BaseReward(state iface.ReadOnlyBeaconState, index types.ValidatorIndex) (uint64, error) {
totalBalance, err := helpers.TotalActiveBalance(state)
if err != nil {
return 0, errors.Wrap(err, "could not calculate active balance")

View File

@@ -4,7 +4,7 @@ import (
"testing"
fuzz "github.com/google/gofuzz"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
ethereum_beacon_p2p_v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -15,7 +15,7 @@ func TestFuzzFinalUpdates_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(base)
s, err := beaconstate.InitializeFromProtoUnsafe(base)
s, err := stateV0.InitializeFromProtoUnsafe(base)
require.NoError(t, err)
_, err = ProcessFinalUpdates(s)
_ = err

View File

@@ -5,11 +5,13 @@ import (
"testing"
"github.com/gogo/protobuf/proto"
types "github.com/prysmaticlabs/eth2-types"
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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -41,7 +43,7 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
indices, err := epoch.UnslashedAttestingIndices(beaconState, atts)
@@ -87,7 +89,7 @@ func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) {
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
indices, err := epoch.UnslashedAttestingIndices(beaconState, atts)
@@ -109,7 +111,7 @@ func TestAttestingBalance_CorrectBalance(t *testing.T) {
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
Source: &ethpb.Checkpoint{Root: make([]byte, 32)},
Slot: uint64(i),
Slot: types.Slot(i),
},
AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
@@ -133,7 +135,7 @@ func TestAttestingBalance_CorrectBalance(t *testing.T) {
Validators: validators,
Balances: balances,
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
balance, err := epoch.AttestingBalance(beaconState, atts)
@@ -159,7 +161,7 @@ func TestBaseReward_AccurateRewards(t *testing.T) {
{ExitEpoch: params.BeaconConfig().FarFutureEpoch, EffectiveBalance: tt.b}},
Balances: []uint64{tt.a},
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
c, err := epoch.BaseReward(beaconState, 0)
require.NoError(t, err)
@@ -174,7 +176,7 @@ func TestProcessSlashings_NotSlashed(t *testing.T) {
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
Slashings: []uint64{0, 1e9},
}
s, err := state.InitializeFromProto(base)
s, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
newState, err := epoch.ProcessSlashings(s)
require.NoError(t, err)
@@ -252,7 +254,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
original := proto.Clone(tt.state)
s, err := state.InitializeFromProto(tt.state)
s, err := stateV0.InitializeFromProto(tt.state)
require.NoError(t, err)
newState, err := epoch.ProcessSlashings(s)
require.NoError(t, err)
@@ -262,7 +264,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
}
func TestProcessFinalUpdates_CanProcess(t *testing.T) {
s := buildState(t, params.BeaconConfig().SlotsPerHistoricalRoot-1, params.BeaconConfig().SlotsPerEpoch)
s := buildState(t, params.BeaconConfig().SlotsPerHistoricalRoot-1, uint64(params.BeaconConfig().SlotsPerEpoch))
ce := helpers.CurrentEpoch(s)
ne := ce + 1
require.NoError(t, s.SetEth1DataVotes([]*ethpb.Eth1Data{}))
@@ -288,13 +290,15 @@ func TestProcessFinalUpdates_CanProcess(t *testing.T) {
assert.Equal(t, newS.Slashings()[ce], newS.Slashings()[ne], "Unexpected slashed balance")
// Verify randao is correctly updated in the right position.
mix, err := newS.RandaoMixAtIndex(ne)
mix, err := newS.RandaoMixAtIndex(uint64(ne))
assert.NoError(t, err)
assert.DeepNotEqual(t, params.BeaconConfig().ZeroHash[:], mix, "latest RANDAO still zero hashes")
// Verify historical root accumulator was appended.
assert.Equal(t, 1, len(newS.HistoricalRoots()), "Unexpected slashed balance")
assert.NotNil(t, newS.CurrentEpochAttestations(), "Nil value stored in current epoch attestations instead of empty slice")
currAtt, err := newS.CurrentEpochAttestations()
require.NoError(t, err)
assert.NotNil(t, currAtt, "Nil value stored in current epoch attestations instead of empty slice")
}
func TestProcessRegistryUpdates_NoRotation(t *testing.T) {
@@ -310,7 +314,7 @@ func TestProcessRegistryUpdates_NoRotation(t *testing.T) {
},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(beaconState)
require.NoError(t, err)
@@ -333,7 +337,7 @@ func TestProcessRegistryUpdates_EligibleToActivate(t *testing.T) {
ActivationEpoch: params.BeaconConfig().FarFutureEpoch,
})
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
currentEpoch := helpers.CurrentEpoch(beaconState)
newState, err := epoch.ProcessRegistryUpdates(beaconState)
@@ -362,7 +366,7 @@ func TestProcessRegistryUpdates_ActivationCompletes(t *testing.T) {
},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(beaconState)
require.NoError(t, err)
@@ -386,7 +390,7 @@ func TestProcessRegistryUpdates_ValidatorsEjected(t *testing.T) {
},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(beaconState)
require.NoError(t, err)
@@ -396,11 +400,11 @@ func TestProcessRegistryUpdates_ValidatorsEjected(t *testing.T) {
}
func TestProcessRegistryUpdates_CanExits(t *testing.T) {
e := uint64(5)
e := types.Epoch(5)
exitEpoch := helpers.ActivationExitEpoch(e)
minWithdrawalDelay := params.BeaconConfig().MinValidatorWithdrawabilityDelay
base := &pb.BeaconState{
Slot: e * params.BeaconConfig().SlotsPerEpoch,
Slot: params.BeaconConfig().SlotsPerEpoch.Mul(uint64(e)),
Validators: []*ethpb.Validator{
{
ExitEpoch: exitEpoch,
@@ -411,7 +415,7 @@ func TestProcessRegistryUpdates_CanExits(t *testing.T) {
},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
newState, err := epoch.ProcessRegistryUpdates(beaconState)
require.NoError(t, err)
@@ -420,7 +424,7 @@ func TestProcessRegistryUpdates_CanExits(t *testing.T) {
}
}
func buildState(t testing.TB, slot, validatorCount uint64) *state.BeaconState {
func buildState(t testing.TB, slot types.Slot, validatorCount uint64) iface.BeaconState {
validators := make([]*ethpb.Validator, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{

View File

@@ -15,13 +15,14 @@ go_library(
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"//shared/traceutil:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
@@ -40,7 +41,7 @@ go_test(
deps = [
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/mathutil:go_default_library",
@@ -49,6 +50,7 @@ go_test(
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
],

View File

@@ -5,8 +5,9 @@ import (
"context"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -18,7 +19,7 @@ import (
// it also tracks and updates epoch attesting balances.
func ProcessAttestations(
ctx context.Context,
state *stateTrie.BeaconState,
state iface.ReadOnlyBeaconState,
vp []*Validator,
pBal *Balance,
) ([]*Validator, *Balance, error) {
@@ -28,7 +29,15 @@ func ProcessAttestations(
v := &Validator{}
var err error
for _, a := range append(state.PreviousEpochAttestations(), state.CurrentEpochAttestations()...) {
prevAtt, err := state.PreviousEpochAttestations()
if err != nil {
return nil, nil, err
}
curAtt, err := state.CurrentEpochAttestations()
if err != nil {
return nil, nil, err
}
for _, a := range append(prevAtt, curAtt...) {
if a.InclusionDelay == 0 {
return nil, nil, errors.New("attestation with inclusion delay of 0")
}
@@ -60,7 +69,7 @@ func ProcessAttestations(
}
// AttestedCurrentEpoch returns true if attestation `a` attested once in current epoch and/or epoch boundary block.
func AttestedCurrentEpoch(s *stateTrie.BeaconState, a *pb.PendingAttestation) (bool, bool, error) {
func AttestedCurrentEpoch(s iface.ReadOnlyBeaconState, a *pb.PendingAttestation) (bool, bool, error) {
currentEpoch := helpers.CurrentEpoch(s)
var votedCurrentEpoch, votedTarget bool
// Did validator vote current epoch.
@@ -78,7 +87,7 @@ func AttestedCurrentEpoch(s *stateTrie.BeaconState, a *pb.PendingAttestation) (b
}
// AttestedPrevEpoch returns true if attestation `a` attested once in previous epoch and epoch boundary block and/or the same head.
func AttestedPrevEpoch(s *stateTrie.BeaconState, a *pb.PendingAttestation) (bool, bool, bool, error) {
func AttestedPrevEpoch(s iface.ReadOnlyBeaconState, a *pb.PendingAttestation) (bool, bool, bool, error) {
prevEpoch := helpers.PrevEpoch(s)
var votedPrevEpoch, votedTarget, votedHead bool
// Did validator vote previous epoch.
@@ -106,7 +115,7 @@ func AttestedPrevEpoch(s *stateTrie.BeaconState, a *pb.PendingAttestation) (bool
}
// SameTarget returns true if attestation `a` attested to the same target block in state.
func SameTarget(state *stateTrie.BeaconState, a *pb.PendingAttestation, e uint64) (bool, error) {
func SameTarget(state iface.ReadOnlyBeaconState, a *pb.PendingAttestation, e types.Epoch) (bool, error) {
r, err := helpers.BlockRoot(state, e)
if err != nil {
return false, err
@@ -118,7 +127,7 @@ func SameTarget(state *stateTrie.BeaconState, a *pb.PendingAttestation, e uint64
}
// SameHead returns true if attestation `a` attested to the same block by attestation slot in state.
func SameHead(state *stateTrie.BeaconState, a *pb.PendingAttestation) (bool, error) {
func SameHead(state iface.ReadOnlyBeaconState, a *pb.PendingAttestation) (bool, error) {
r, err := helpers.BlockRootAtSlot(state, a.Data.Slot)
if err != nil {
return false, err
@@ -130,7 +139,7 @@ func SameHead(state *stateTrie.BeaconState, a *pb.PendingAttestation) (bool, err
}
// UpdateValidator updates pre computed validator store.
func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb.PendingAttestation, aSlot uint64) []*Validator {
func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *pb.PendingAttestation, aSlot types.Slot) []*Validator {
inclusionSlot := aSlot + a.InclusionDelay
for _, i := range indices {

View File

@@ -17,7 +17,7 @@ import (
)
func TestUpdateValidator_Works(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
e := params.BeaconConfig().FarFutureSlot
vp := []*precompute.Validator{{}, {InclusionSlot: e}, {}, {InclusionSlot: e}, {}, {InclusionSlot: e}}
record := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true,
IsPrevEpochAttester: true, IsPrevEpochTargetAttester: true, IsPrevEpochHeadAttester: true}
@@ -34,7 +34,7 @@ func TestUpdateValidator_Works(t *testing.T) {
}
func TestUpdateValidator_InclusionOnlyCountsPrevEpoch(t *testing.T) {
e := params.BeaconConfig().FarFutureEpoch
e := params.BeaconConfig().FarFutureSlot
vp := []*precompute.Validator{{InclusionSlot: e}}
record := &precompute.Validator{IsCurrentEpochAttester: true, IsCurrentEpochTargetAttester: true}
a := &pb.PendingAttestation{InclusionDelay: 1, ProposerIndex: 2}
@@ -170,9 +170,9 @@ func TestProcessAttestations(t *testing.T) {
require.NoError(t, beaconState.SetBlockRoots(br))
att2.Data.Target.Root = newRt[:]
att2.Data.BeaconBlockRoot = newRt[:]
err := beaconState.SetPreviousEpochAttestations([]*pb.PendingAttestation{{Data: att1.Data, AggregationBits: bf, InclusionDelay: 1}})
err := beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{Data: att1.Data, AggregationBits: bf, InclusionDelay: 1})
require.NoError(t, err)
err = beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{{Data: att2.Data, AggregationBits: bf, InclusionDelay: 1}})
err = beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{Data: att2.Data, AggregationBits: bf, InclusionDelay: 1})
require.NoError(t, err)
pVals := make([]*precompute.Validator, validators)

View File

@@ -4,7 +4,7 @@ import (
"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"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
)
// ProcessJustificationAndFinalizationPreCompute processes justification and finalization during
@@ -48,7 +48,7 @@ import (
// # The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
// if all(bits[0:2]) and old_current_justified_checkpoint.epoch + 1 == current_epoch:
// state.finalized_checkpoint = old_current_justified_checkpoint
func ProcessJustificationAndFinalizationPreCompute(state *stateTrie.BeaconState, pBal *Balance) (*stateTrie.BeaconState, error) {
func ProcessJustificationAndFinalizationPreCompute(state iface.BeaconState, pBal *Balance) (iface.BeaconState, error) {
canProcessSlot, err := helpers.StartSlot(2 /*epoch*/)
if err != nil {
return nil, err

View File

@@ -3,10 +3,11 @@ package precompute_test
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -36,18 +37,18 @@ func TestProcessJustificationAndFinalizationPreCompute_ConsecutiveEpochs(t *test
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
BlockRoots: blockRoots,
}
state, err := beaconstate.InitializeFromProto(base)
state, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
attestedBalance := 4 * e * 3 / 2
attestedBalance := 4 * uint64(e) * 3 / 2
b := &precompute.Balance{PrevEpochTargetAttested: attestedBalance}
newState, err := precompute.ProcessJustificationAndFinalizationPreCompute(state, b)
require.NoError(t, err)
rt := [32]byte{byte(64)}
assert.DeepEqual(t, rt[:], newState.CurrentJustifiedCheckpoint().Root, "Unexpected justified root")
assert.Equal(t, uint64(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.Equal(t, uint64(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.Equal(t, types.Epoch(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.Equal(t, types.Epoch(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], newState.FinalizedCheckpoint().Root, "Unexpected finalized root")
assert.Equal(t, uint64(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
assert.Equal(t, types.Epoch(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
}
func TestProcessJustificationAndFinalizationPreCompute_JustifyCurrentEpoch(t *testing.T) {
@@ -73,18 +74,18 @@ func TestProcessJustificationAndFinalizationPreCompute_JustifyCurrentEpoch(t *te
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
BlockRoots: blockRoots,
}
state, err := beaconstate.InitializeFromProto(base)
state, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
attestedBalance := 4 * e * 3 / 2
attestedBalance := 4 * uint64(e) * 3 / 2
b := &precompute.Balance{PrevEpochTargetAttested: attestedBalance}
newState, err := precompute.ProcessJustificationAndFinalizationPreCompute(state, b)
require.NoError(t, err)
rt := [32]byte{byte(64)}
assert.DeepEqual(t, rt[:], newState.CurrentJustifiedCheckpoint().Root, "Unexpected current justified root")
assert.Equal(t, uint64(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.Equal(t, uint64(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.Equal(t, types.Epoch(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.Equal(t, types.Epoch(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], newState.FinalizedCheckpoint().Root)
assert.Equal(t, uint64(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
assert.Equal(t, types.Epoch(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
}
func TestProcessJustificationAndFinalizationPreCompute_JustifyPrevEpoch(t *testing.T) {
@@ -109,16 +110,16 @@ func TestProcessJustificationAndFinalizationPreCompute_JustifyPrevEpoch(t *testi
Balances: []uint64{a, a, a, a}, // validator total balance should be 128000000000
BlockRoots: blockRoots, FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
state, err := beaconstate.InitializeFromProto(base)
state, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
attestedBalance := 4 * e * 3 / 2
attestedBalance := 4 * uint64(e) * 3 / 2
b := &precompute.Balance{PrevEpochTargetAttested: attestedBalance}
newState, err := precompute.ProcessJustificationAndFinalizationPreCompute(state, b)
require.NoError(t, err)
rt := [32]byte{byte(64)}
assert.DeepEqual(t, rt[:], newState.CurrentJustifiedCheckpoint().Root, "Unexpected current justified root")
assert.Equal(t, uint64(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.Equal(t, uint64(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.Equal(t, types.Epoch(0), newState.PreviousJustifiedCheckpoint().Epoch, "Unexpected previous justified epoch")
assert.Equal(t, types.Epoch(2), newState.CurrentJustifiedCheckpoint().Epoch, "Unexpected justified epoch")
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], newState.FinalizedCheckpoint().Root)
assert.Equal(t, uint64(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
assert.Equal(t, types.Epoch(0), newState.FinalizedCheckpointEpoch(), "Unexpected finalized epoch")
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -16,16 +16,17 @@ import (
// New gets called at the beginning of process epoch cycle to return
// pre computed instances of validators attesting records and total
// balances attested in an epoch.
func New(ctx context.Context, state *stateTrie.BeaconState) ([]*Validator, *Balance, error) {
func New(ctx context.Context, state iface.BeaconState) ([]*Validator, *Balance, error) {
ctx, span := trace.StartSpan(ctx, "precomputeEpoch.New")
defer span.End()
pValidators := make([]*Validator, state.NumValidators())
pBal := &Balance{}
currentEpoch := helpers.CurrentEpoch(state)
prevEpoch := helpers.PrevEpoch(state)
if err := state.ReadFromEveryValidator(func(idx int, val stateTrie.ReadOnlyValidator) error {
if err := state.ReadFromEveryValidator(func(idx int, val iface.ReadOnlyValidator) error {
// Was validator withdrawable or slashed
withdrawable := prevEpoch+1 >= val.WithdrawableEpoch()
pVal := &Validator{
@@ -45,8 +46,8 @@ func New(ctx context.Context, state *stateTrie.BeaconState) ([]*Validator, *Bala
}
// Set inclusion slot and inclusion distance to be max, they will be compared and replaced
// with the lower values
pVal.InclusionSlot = params.BeaconConfig().FarFutureEpoch
pVal.InclusionDistance = params.BeaconConfig().FarFutureEpoch
pVal.InclusionSlot = params.BeaconConfig().FarFutureSlot
pVal.InclusionDistance = params.BeaconConfig().FarFutureSlot
pValidators[idx] = pVal
return nil

View File

@@ -6,7 +6,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -15,7 +15,7 @@ import (
func TestNew(t *testing.T) {
ffe := params.BeaconConfig().FarFutureEpoch
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
s, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: params.BeaconConfig().SlotsPerEpoch,
// Validator 0 is slashed
// Validator 1 is withdrawable
@@ -29,7 +29,7 @@ func TestNew(t *testing.T) {
},
})
require.NoError(t, err)
e := params.BeaconConfig().FarFutureEpoch
e := params.BeaconConfig().FarFutureSlot
v, b, err := precompute.New(context.Background(), s)
require.NoError(t, err)
assert.DeepEqual(t, &precompute.Validator{

View File

@@ -2,8 +2,9 @@ package precompute
import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -11,10 +12,10 @@ import (
// ProcessRewardsAndPenaltiesPrecompute processes the rewards and penalties of individual validator.
// This is an optimized version by passing in precomputed validator attesting records and and total epoch balances.
func ProcessRewardsAndPenaltiesPrecompute(
state *stateTrie.BeaconState,
state iface.BeaconState,
pBal *Balance,
vp []*Validator,
) (*stateTrie.BeaconState, error) {
) (iface.BeaconState, error) {
// Can't process rewards and penalties in genesis epoch.
if helpers.CurrentEpoch(state) == 0 {
return state, nil
@@ -55,7 +56,7 @@ func ProcessRewardsAndPenaltiesPrecompute(
// AttestationsDelta computes and returns the rewards and penalties differences for individual validators based on the
// voting records.
func AttestationsDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Validator) ([]uint64, []uint64, error) {
func AttestationsDelta(state iface.ReadOnlyBeaconState, pBal *Balance, vp []*Validator) ([]uint64, []uint64, error) {
numOfVals := state.NumValidators()
rewards := make([]uint64, numOfVals)
penalties := make([]uint64, numOfVals)
@@ -68,7 +69,7 @@ func AttestationsDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Valida
return rewards, penalties, nil
}
func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uint64) (uint64, uint64) {
func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch types.Epoch) (uint64, uint64) {
eligible := v.IsActivePrevEpoch || (v.IsSlashed && !v.IsWithdrawableCurrentEpoch)
if !eligible || pBal.ActiveCurrentEpoch == 0 {
return 0, 0
@@ -85,9 +86,9 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
if v.IsPrevEpochAttester && !v.IsSlashed {
proposerReward := br / params.BeaconConfig().ProposerRewardQuotient
maxAttesterReward := br - proposerReward
r += maxAttesterReward / v.InclusionDistance
r += maxAttesterReward / uint64(v.InclusionDistance)
if isInInactivityLeak(prevEpoch, finalizedEpoch) {
if helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch) {
// Since full base reward will be canceled out by inactivity penalty deltas,
// optimal participation receives full base reward compensation here.
r += br
@@ -102,7 +103,7 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
// Process target reward / penalty
if v.IsPrevEpochTargetAttester && !v.IsSlashed {
if isInInactivityLeak(prevEpoch, finalizedEpoch) {
if helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch) {
// Since full base reward will be canceled out by inactivity penalty deltas,
// optimal participation receives full base reward compensation here.
r += br
@@ -116,7 +117,7 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
// Process head reward / penalty
if v.IsPrevEpochHeadAttester && !v.IsSlashed {
if isInInactivityLeak(prevEpoch, finalizedEpoch) {
if helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch) {
// Since full base reward will be canceled out by inactivity penalty deltas,
// optimal participation receives full base reward compensation here.
r += br
@@ -129,9 +130,9 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
}
// Process finality delay penalty
finalityDelay := finalityDelay(prevEpoch, finalizedEpoch)
finalityDelay := helpers.FinalityDelay(prevEpoch, finalizedEpoch)
if isInInactivityLeak(prevEpoch, finalizedEpoch) {
if helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch) {
// If validator is performing optimally, this cancels all rewards for a neutral balance.
proposerReward := br / params.BeaconConfig().ProposerRewardQuotient
p += baseRewardsPerEpoch*br - proposerReward
@@ -139,7 +140,7 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
// Equivalent to the following condition from the spec:
// `index not in get_unslashed_attesting_indices(state, matching_target_attestations)`
if !v.IsPrevEpochTargetAttester || v.IsSlashed {
p += vb * finalityDelay / params.BeaconConfig().InactivityPenaltyQuotient
p += vb * uint64(finalityDelay) / params.BeaconConfig().InactivityPenaltyQuotient
}
}
return r, p
@@ -147,7 +148,7 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch uin
// ProposersDelta computes and returns the rewards and penalties differences for individual validators based on the
// proposer inclusion records.
func ProposersDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Validator) ([]uint64, error) {
func ProposersDelta(state iface.ReadOnlyBeaconState, pBal *Balance, vp []*Validator) ([]uint64, error) {
numofVals := state.NumValidators()
rewards := make([]uint64, numofVals)
@@ -162,7 +163,7 @@ func ProposersDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Validator
baseRewardsPerEpoch := params.BeaconConfig().BaseRewardsPerEpoch
proposerRewardQuotient := params.BeaconConfig().ProposerRewardQuotient
for _, v := range vp {
if v.ProposerIndex >= uint64(len(rewards)) {
if uint64(v.ProposerIndex) >= uint64(len(rewards)) {
// This should never happen with a valid state / validator.
return nil, errors.New("proposer index out of range")
}
@@ -176,21 +177,3 @@ func ProposersDelta(state *stateTrie.BeaconState, pBal *Balance, vp []*Validator
}
return rewards, nil
}
// isInInactivityLeak returns true if the state is experiencing inactivity leak.
//
// Spec code:
// def is_in_inactivity_leak(state: BeaconState) -> bool:
// return get_finality_delay(state) > MIN_EPOCHS_TO_INACTIVITY_PENALTY
func isInInactivityLeak(prevEpoch, finalizedEpoch uint64) bool {
return finalityDelay(prevEpoch, finalizedEpoch) > params.BeaconConfig().MinEpochsToInactivityPenalty
}
// finalityDelay returns the finality delay using the beacon state.
//
// Spec code:
// def get_finality_delay(state: BeaconState) -> uint64:
// return get_previous_epoch(state) - state.finalized_checkpoint.epoch
func finalityDelay(prevEpoch, finalizedEpoch uint64) uint64 {
return prevEpoch - finalizedEpoch
}

View File

@@ -4,11 +4,12 @@ import (
"context"
"testing"
types "github.com/prysmaticlabs/eth2-types"
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"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -33,7 +34,7 @@ func TestProcessRewardsAndPenaltiesPrecompute(t *testing.T) {
}
base.PreviousEpochAttestations = atts
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
vp, bp, err := New(context.Background(), beaconState)
@@ -41,8 +42,10 @@ func TestProcessRewardsAndPenaltiesPrecompute(t *testing.T) {
vp, bp, err = ProcessAttestations(context.Background(), beaconState, vp, bp)
require.NoError(t, err)
beaconState, err = ProcessRewardsAndPenaltiesPrecompute(beaconState, bp, vp)
processedState, err := ProcessRewardsAndPenaltiesPrecompute(beaconState, bp, vp)
require.NoError(t, err)
beaconState, ok := processedState.(*stateV0.BeaconState)
require.Equal(t, true, ok)
// Indices that voted everything except for head, lost a bit money
wanted := uint64(31999810265)
@@ -75,9 +78,9 @@ func TestAttestationDeltaPrecompute(t *testing.T) {
}
}
base.PreviousEpochAttestations = atts
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
slashedAttestedIndices := []uint64{1413}
slashedAttestedIndices := []types.ValidatorIndex{1413}
for _, i := range slashedAttestedIndices {
vs := beaconState.Validators()
vs[i].Slashed = true
@@ -100,7 +103,7 @@ func TestAttestationDeltaPrecompute(t *testing.T) {
totalBalance, err := helpers.TotalActiveBalance(beaconState)
require.NoError(t, err)
attestedIndices := []uint64{55, 1339, 1746, 1811, 1569}
attestedIndices := []types.ValidatorIndex{55, 1339, 1746, 1811, 1569}
for _, i := range attestedIndices {
base, err := epoch.BaseReward(beaconState, i)
require.NoError(t, err, "Could not get base reward")
@@ -112,7 +115,7 @@ func TestAttestationDeltaPrecompute(t *testing.T) {
// Base rewards for proposer and attesters working together getting attestation
// on chain in the fatest manner
proposerReward := base / params.BeaconConfig().ProposerRewardQuotient
wanted += (base-proposerReward)*params.BeaconConfig().MinAttestationInclusionDelay - 1
wanted += (base-proposerReward)*uint64(params.BeaconConfig().MinAttestationInclusionDelay) - 1
assert.Equal(t, wanted, rewards[i], "Unexpected reward balance for validator with index %d", i)
// Since all these validators attested, they shouldn't get penalized.
assert.Equal(t, uint64(0), penalties[i], "Unexpected penalty balance")
@@ -125,7 +128,7 @@ func TestAttestationDeltaPrecompute(t *testing.T) {
assert.Equal(t, 3*base, penalties[i], "Unexpected slashed indices penalty balance")
}
nonAttestedIndices := []uint64{434, 677, 872, 791}
nonAttestedIndices := []types.ValidatorIndex{434, 677, 872, 791}
for _, i := range nonAttestedIndices {
base, err := epoch.BaseReward(beaconState, i)
assert.NoError(t, err, "Could not get base reward")
@@ -159,7 +162,7 @@ func TestAttestationDeltas_ZeroEpoch(t *testing.T) {
}
}
base.PreviousEpochAttestations = atts
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
pVals, pBal, err := New(context.Background(), beaconState)
@@ -197,7 +200,7 @@ func TestAttestationDeltas_ZeroInclusionDelay(t *testing.T) {
}
}
base.PreviousEpochAttestations = atts
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
pVals, pBal, err := New(context.Background(), beaconState)
@@ -223,11 +226,11 @@ func TestProcessRewardsAndPenaltiesPrecompute_SlashedInactivePenalty(t *testing.
}
base.PreviousEpochAttestations = atts
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch*10))
slashedAttestedIndices := []uint64{14, 37, 68, 77, 139}
slashedAttestedIndices := []types.ValidatorIndex{14, 37, 68, 77, 139}
for _, i := range slashedAttestedIndices {
vs := beaconState.Validators()
vs[i].Slashed = true
@@ -248,13 +251,13 @@ func TestProcessRewardsAndPenaltiesPrecompute_SlashedInactivePenalty(t *testing.
penalty := 3 * base
proposerReward := base / params.BeaconConfig().ProposerRewardQuotient
penalty += params.BeaconConfig().BaseRewardsPerEpoch*base - proposerReward
penalty += vp[i].CurrentEpochEffectiveBalance * finalityDelay / params.BeaconConfig().InactivityPenaltyQuotient
penalty += vp[i].CurrentEpochEffectiveBalance * uint64(finalityDelay) / params.BeaconConfig().InactivityPenaltyQuotient
assert.Equal(t, penalty, penalties[i], "Unexpected slashed indices penalty balance")
assert.Equal(t, uint64(0), rewards[i], "Unexpected slashed indices reward balance")
}
}
func buildState(slot, validatorCount uint64) *pb.BeaconState {
func buildState(slot types.Slot, validatorCount uint64) *pb.BeaconState {
validators := make([]*ethpb.Validator, validatorCount)
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
@@ -297,10 +300,10 @@ func TestProposerDeltaPrecompute_HappyCase(t *testing.T) {
e := params.BeaconConfig().SlotsPerEpoch
validatorCount := uint64(10)
base := buildState(e, validatorCount)
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
proposerIndex := uint64(1)
proposerIndex := types.ValidatorIndex(1)
b := &Balance{ActiveCurrentEpoch: 1000}
v := []*Validator{
{IsPrevEpochAttester: true, CurrentEpochEffectiveBalance: 32, ProposerIndex: proposerIndex},
@@ -319,10 +322,10 @@ func TestProposerDeltaPrecompute_ValidatorIndexOutOfRange(t *testing.T) {
e := params.BeaconConfig().SlotsPerEpoch
validatorCount := uint64(10)
base := buildState(e, validatorCount)
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
proposerIndex := validatorCount
proposerIndex := types.ValidatorIndex(validatorCount)
b := &Balance{ActiveCurrentEpoch: 1000}
v := []*Validator{
{IsPrevEpochAttester: true, CurrentEpochEffectiveBalance: 32, ProposerIndex: proposerIndex},
@@ -335,10 +338,10 @@ func TestProposerDeltaPrecompute_SlashedCase(t *testing.T) {
e := params.BeaconConfig().SlotsPerEpoch
validatorCount := uint64(10)
base := buildState(e, validatorCount)
beaconState, err := state.InitializeFromProto(base)
beaconState, err := stateV0.InitializeFromProto(base)
require.NoError(t, err)
proposerIndex := uint64(1)
proposerIndex := types.ValidatorIndex(1)
b := &Balance{ActiveCurrentEpoch: 1000}
v := []*Validator{
{IsPrevEpochAttester: true, CurrentEpochEffectiveBalance: 32, ProposerIndex: proposerIndex, IsSlashed: true},
@@ -347,55 +350,3 @@ func TestProposerDeltaPrecompute_SlashedCase(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, uint64(0), r[proposerIndex], "Unexpected proposer reward for slashed")
}
func TestFinalityDelay(t *testing.T) {
base := buildState(params.BeaconConfig().SlotsPerEpoch*10, 1)
base.FinalizedCheckpoint = &ethpb.Checkpoint{Epoch: 3}
beaconState, err := state.InitializeFromProto(base)
require.NoError(t, err)
prevEpoch := uint64(0)
finalizedEpoch := uint64(0)
// Set values for each test case
setVal := func() {
prevEpoch = helpers.PrevEpoch(beaconState)
finalizedEpoch = beaconState.FinalizedCheckpointEpoch()
}
setVal()
d := finalityDelay(prevEpoch, finalizedEpoch)
w := helpers.PrevEpoch(beaconState) - beaconState.FinalizedCheckpointEpoch()
assert.Equal(t, w, d, "Did not get wanted finality delay")
require.NoError(t, beaconState.SetFinalizedCheckpoint(&ethpb.Checkpoint{Epoch: 4}))
setVal()
d = finalityDelay(prevEpoch, finalizedEpoch)
w = helpers.PrevEpoch(beaconState) - beaconState.FinalizedCheckpointEpoch()
assert.Equal(t, w, d, "Did not get wanted finality delay")
require.NoError(t, beaconState.SetFinalizedCheckpoint(&ethpb.Checkpoint{Epoch: 5}))
setVal()
d = finalityDelay(prevEpoch, finalizedEpoch)
w = helpers.PrevEpoch(beaconState) - beaconState.FinalizedCheckpointEpoch()
assert.Equal(t, w, d, "Did not get wanted finality delay")
}
func TestIsInInactivityLeak(t *testing.T) {
base := buildState(params.BeaconConfig().SlotsPerEpoch*10, 1)
base.FinalizedCheckpoint = &ethpb.Checkpoint{Epoch: 3}
beaconState, err := state.InitializeFromProto(base)
require.NoError(t, err)
prevEpoch := uint64(0)
finalizedEpoch := uint64(0)
// Set values for each test case
setVal := func() {
prevEpoch = helpers.PrevEpoch(beaconState)
finalizedEpoch = beaconState.FinalizedCheckpointEpoch()
}
setVal()
assert.Equal(t, true, isInInactivityLeak(prevEpoch, finalizedEpoch), "Wanted inactivity leak true")
require.NoError(t, beaconState.SetFinalizedCheckpoint(&ethpb.Checkpoint{Epoch: 4}))
setVal()
assert.Equal(t, true, isInInactivityLeak(prevEpoch, finalizedEpoch), "Wanted inactivity leak true")
require.NoError(t, beaconState.SetFinalizedCheckpoint(&ethpb.Checkpoint{Epoch: 5}))
setVal()
assert.Equal(t, false, isInInactivityLeak(prevEpoch, finalizedEpoch), "Wanted inactivity leak false")
}

View File

@@ -1,16 +1,17 @@
package precompute
import (
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessSlashingsPrecompute processes the slashed validators during epoch processing.
// This is an optimized version by passing in precomputed total epoch balances.
func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, pBal *Balance) error {
func ProcessSlashingsPrecompute(state iface.BeaconState, pBal *Balance) error {
currentEpoch := helpers.CurrentEpoch(state)
exitLength := params.BeaconConfig().EpochsPerSlashingsVector
@@ -26,7 +27,7 @@ func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, pBal *Balance) err
var hasSlashing bool
// Iterate through validator list in state, stop until a validator satisfies slashing condition of current epoch.
err := state.ReadFromEveryValidator(func(idx int, val stateTrie.ReadOnlyValidator) error {
err := state.ReadFromEveryValidator(func(idx int, val iface.ReadOnlyValidator) error {
correctEpoch := epochToWithdraw == val.WithdrawableEpoch()
if val.Slashed() && correctEpoch {
hasSlashing = true
@@ -42,17 +43,17 @@ func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, pBal *Balance) err
}
increment := params.BeaconConfig().EffectiveBalanceIncrement
validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
validatorFunc := func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
correctEpoch := epochToWithdraw == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / pBal.ActiveCurrentEpoch * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
return false, err
if err := helpers.DecreaseBalance(state, types.ValidatorIndex(idx), penalty); err != nil {
return false, val, err
}
return true, nil
return true, val, nil
}
return false, nil
return false, val, nil
}
return state.ApplyToEveryValidator(validatorFunc)

View File

@@ -7,7 +7,7 @@ import (
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -15,7 +15,7 @@ import (
)
func TestProcessSlashingsPrecompute_NotSlashedWithSlashedTrue(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
s, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 0,
Validators: []*ethpb.Validator{{Slashed: true}},
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
@@ -30,7 +30,7 @@ func TestProcessSlashingsPrecompute_NotSlashedWithSlashedTrue(t *testing.T) {
}
func TestProcessSlashingsPrecompute_NotSlashedWithSlashedFalse(t *testing.T) {
s, err := beaconstate.InitializeFromProto(&pb.BeaconState{
s, err := stateV0.InitializeFromProto(&pb.BeaconState{
Slot: 0,
Validators: []*ethpb.Validator{{}},
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
@@ -124,7 +124,7 @@ func TestProcessSlashingsPrecompute_SlashedLess(t *testing.T) {
pBal := &precompute.Balance{ActiveCurrentEpoch: ab}
original := proto.Clone(tt.state)
state, err := beaconstate.InitializeFromProto(tt.state)
state, err := stateV0.InitializeFromProto(tt.state)
require.NoError(t, err)
require.NoError(t, precompute.ProcessSlashingsPrecompute(state, pBal))
assert.Equal(t, tt.want, state.Balances()[0], "ProcessSlashings({%v}) = newState; newState.Balances[0] = %d; wanted %d", original, state.Balances()[0])

View File

@@ -29,7 +29,7 @@ go_test(
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",
@@ -62,7 +62,7 @@ go_test(
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",

View File

@@ -9,7 +9,7 @@ import (
"github.com/ghodss/yaml"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -44,7 +44,7 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) {
require.NoError(t, err)
preBeaconStateBase := &pb.BeaconState{}
require.NoError(t, preBeaconStateBase.UnmarshalSSZ(preBeaconStateFile), "Failed to unmarshal")
preBeaconState, err := beaconstate.InitializeFromProto(preBeaconStateBase)
preBeaconState, err := stateV0.InitializeFromProto(preBeaconStateBase)
require.NoError(t, err)
vp, bp, err := precompute.New(ctx, preBeaconState)

View File

@@ -1,5 +1,7 @@
package precompute
import types "github.com/prysmaticlabs/eth2-types"
// Validator stores the pre computation of individual validator's attesting records these records
// consist of attestation votes, block inclusion record. Pre computing and storing such record
// is essential for process epoch optimizations.
@@ -26,11 +28,11 @@ type Validator struct {
// CurrentEpochEffectiveBalance is how much effective balance this validator validator has current epoch.
CurrentEpochEffectiveBalance uint64
// InclusionSlot is the slot of when the attestation gets included in the chain.
InclusionSlot uint64
InclusionSlot types.Slot
// InclusionDistance is the distance between the assigned slot and this validator's attestation was included in block.
InclusionDistance uint64
InclusionDistance types.Slot
// ProposerIndex is the index of proposer at slot where this validator's attestation was included.
ProposerIndex uint64
ProposerIndex types.ValidatorIndex
// BeforeEpochTransitionBalance is the validator balance prior to epoch transition.
BeforeEpochTransitionBalance uint64
// AfterEpochTransitionBalance is the validator balance after epoch transition.

View File

@@ -28,7 +28,8 @@ go_test(
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",
@@ -60,7 +61,8 @@ go_test(
"//beacon-chain/core/epoch:go_default_library",
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/params:go_default_library",
"//shared/params/spectest:go_default_library",

View File

@@ -5,7 +5,7 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/params/spectest"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -23,7 +23,7 @@ func runFinalUpdatesTests(t *testing.T, config string) {
}
}
func processFinalUpdatesWrapper(t *testing.T, state *beaconstate.BeaconState) (*beaconstate.BeaconState, error) {
func processFinalUpdatesWrapper(t *testing.T, state iface.BeaconState) (iface.BeaconState, error) {
state, err := epoch.ProcessFinalUpdates(state)
require.NoError(t, err, "Could not process final updates")
return state, nil

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