mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 13:58:09 -05:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e33850bf51 | ||
|
|
cc643ac4cc | ||
|
|
abefe1e9d5 | ||
|
|
b4e89fb28b | ||
|
|
4ad1c4df01 | ||
|
|
6a197b47d9 | ||
|
|
d102421a25 | ||
|
|
7b1490429c | ||
|
|
bbdf19cfd0 | ||
|
|
5d94030b4f | ||
|
|
16273a2040 | ||
|
|
97663548a1 | ||
|
|
7d9d8454b1 | ||
|
|
21bdbd548a | ||
|
|
e2caaf972f | ||
|
|
c5ddc266ae | ||
|
|
74518f0e1b | ||
|
|
122c3f44cc | ||
|
|
b1b13cfca7 | ||
|
|
495013e832 | ||
|
|
ae82c17dc3 | ||
|
|
8bd1f16223 | ||
|
|
58b18c7996 | ||
|
|
dda48c452d | ||
|
|
025d053fa4 | ||
|
|
7af89a82c9 | ||
|
|
10e1f04ce4 | ||
|
|
5817090b59 | ||
|
|
df695346a5 | ||
|
|
f9b4a340a3 | ||
|
|
d2dbc13427 | ||
|
|
e5e4dee629 | ||
|
|
ab2b0c5c99 | ||
|
|
7c3147ca89 | ||
|
|
03ae8672b6 | ||
|
|
f763b35494 | ||
|
|
51581e9b6e | ||
|
|
e5ee7f7e8b | ||
|
|
d0fabd86fb | ||
|
|
5315c45453 | ||
|
|
55883876e4 | ||
|
|
1d587c0e95 | ||
|
|
d4fa490dec | ||
|
|
59041cf868 | ||
|
|
8f1ee146a9 | ||
|
|
a5f1dcaa65 | ||
|
|
9615484fe9 | ||
|
|
5ad4f14ffc | ||
|
|
4c869fa587 | ||
|
|
20ab988a4a | ||
|
|
16bbf5602f | ||
|
|
f9113dfd06 | ||
|
|
0faf7ac01f | ||
|
|
9d2bdfe14d | ||
|
|
ad03938964 | ||
|
|
84916672c6 | ||
|
|
2f29bb64f6 | ||
|
|
156e40e886 | ||
|
|
b7a82d0fd1 | ||
|
|
61bfb77120 | ||
|
|
7b03d901ee | ||
|
|
7a3df7642b | ||
|
|
231208c977 | ||
|
|
001f719cc3 | ||
|
|
58ad800553 | ||
|
|
2060f876b1 | ||
|
|
e226237590 | ||
|
|
314ef8e1bd | ||
|
|
a428664eb5 | ||
|
|
7c3d89b25f | ||
|
|
f4c004085b | ||
|
|
c0e207eb47 | ||
|
|
7003d97061 | ||
|
|
957d853a2f | ||
|
|
29695d8906 | ||
|
|
a8ba5e7dd8 | ||
|
|
0ad190c1fb | ||
|
|
2e056b38da | ||
|
|
966de59478 | ||
|
|
c8919bd233 | ||
|
|
baa2e2e340 | ||
|
|
7765d275d1 | ||
|
|
2fd7c926ed | ||
|
|
21fc9853ee | ||
|
|
642de455d5 | ||
|
|
d371cd6e89 | ||
|
|
c8a7f6f0bd | ||
|
|
d7a7fa025d | ||
|
|
6b6ac4c3fb | ||
|
|
3b8651cbf4 | ||
|
|
9d29d2f4bf | ||
|
|
3d205a387c | ||
|
|
269b382229 | ||
|
|
80ebbcf03e | ||
|
|
32ebe94515 | ||
|
|
d2f4a8cc7c | ||
|
|
982de94428 | ||
|
|
a41025e5ec | ||
|
|
3ce26ae7e2 | ||
|
|
1acedd5b01 | ||
|
|
a0679c70d3 | ||
|
|
7f53700306 | ||
|
|
3b69f7a196 | ||
|
|
72562dcf3a | ||
|
|
cc23b8311a | ||
|
|
cbe54fe3f9 | ||
|
|
1b6adca3ca | ||
|
|
1651649e5a | ||
|
|
56187edb98 | ||
|
|
ecad5bbffc | ||
|
|
407182387b | ||
|
|
ad0b0b503d | ||
|
|
58f4ba758c | ||
|
|
64f64f06bf | ||
|
|
e70055733f | ||
|
|
36e4f49af0 | ||
|
|
d98428dec4 | ||
|
|
00b92e01d3 | ||
|
|
ca5adbf7e4 | ||
|
|
a083b7a0a5 | ||
|
|
dd5995b665 |
17
.github/workflows/go.yml
vendored
17
.github/workflows/go.yml
vendored
@@ -38,10 +38,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Set up Go 1.17
|
- name: Set up Go 1.18
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18
|
||||||
- name: Run Gosec Security Scanner
|
- name: Run Gosec Security Scanner
|
||||||
run: | # https://github.com/securego/gosec/issues/469
|
run: | # https://github.com/securego/gosec/issues/469
|
||||||
export PATH=$PATH:$(go env GOPATH)/bin
|
export PATH=$PATH:$(go env GOPATH)/bin
|
||||||
@@ -55,16 +55,16 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Set up Go 1.17
|
- name: Set up Go 1.18
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Golangci-lint
|
- name: Golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v2
|
||||||
with:
|
with:
|
||||||
args: --print-issued-lines --sort-results --no-config --timeout=10m --disable-all -E deadcode -E errcheck -E gosimple --skip-files=validator/web/site_data.go --skip-dirs=proto --go=1.17
|
args: --print-issued-lines --sort-results --no-config --timeout=10m --disable-all -E deadcode -E errcheck -E gosimple --skip-files=validator/web/site_data.go --skip-dirs=proto --go=1.18
|
||||||
version: v1.45.2
|
version: v1.45.2
|
||||||
skip-go-installation: true
|
skip-go-installation: true
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
@@ -89,6 +89,11 @@ jobs:
|
|||||||
# Use blst tag to allow go and bazel builds for blst.
|
# Use blst tag to allow go and bazel builds for blst.
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
|
|
||||||
|
# fuzz and blst_disabled leverage go tag based stubs at compile time.
|
||||||
|
# Building with these tags should be checked and enforced at pre-submit.
|
||||||
|
- name: Build for fuzzing
|
||||||
|
run: go build -tags=fuzz,blst_disabled ./...
|
||||||
|
|
||||||
# Tests run via Bazel for now...
|
# Tests run via Bazel for now...
|
||||||
# - name: Test
|
# - name: Test
|
||||||
# run: go test -v ./...
|
# run: go test -v ./...
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -32,3 +32,6 @@ dist
|
|||||||
|
|
||||||
# deepsource cli
|
# deepsource cli
|
||||||
bin
|
bin
|
||||||
|
|
||||||
|
# p2p metaData
|
||||||
|
metaData
|
||||||
|
|||||||
13
BUILD.bazel
13
BUILD.bazel
@@ -115,18 +115,19 @@ nogo(
|
|||||||
"@org_golang_x_tools//go/analysis/passes/assign:go_default_library",
|
"@org_golang_x_tools//go/analysis/passes/assign:go_default_library",
|
||||||
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
|
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
|
||||||
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_default_library",
|
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_default_library",
|
||||||
"//tools/analyzers/maligned:go_default_library",
|
"//tools/analyzers/comparesame:go_default_library",
|
||||||
"//tools/analyzers/cryptorand:go_default_library",
|
"//tools/analyzers/cryptorand:go_default_library",
|
||||||
"//tools/analyzers/errcheck:go_default_library",
|
"//tools/analyzers/errcheck:go_default_library",
|
||||||
"//tools/analyzers/featureconfig:go_default_library",
|
"//tools/analyzers/featureconfig:go_default_library",
|
||||||
"//tools/analyzers/comparesame:go_default_library",
|
"//tools/analyzers/gocognit:go_default_library",
|
||||||
"//tools/analyzers/shadowpredecl:go_default_library",
|
|
||||||
"//tools/analyzers/nop:go_default_library",
|
|
||||||
"//tools/analyzers/slicedirect:go_default_library",
|
|
||||||
"//tools/analyzers/interfacechecker:go_default_library",
|
|
||||||
"//tools/analyzers/ineffassign:go_default_library",
|
"//tools/analyzers/ineffassign:go_default_library",
|
||||||
|
"//tools/analyzers/interfacechecker:go_default_library",
|
||||||
|
"//tools/analyzers/maligned:go_default_library",
|
||||||
|
"//tools/analyzers/nop:go_default_library",
|
||||||
"//tools/analyzers/properpermissions:go_default_library",
|
"//tools/analyzers/properpermissions:go_default_library",
|
||||||
"//tools/analyzers/recursivelock:go_default_library",
|
"//tools/analyzers/recursivelock:go_default_library",
|
||||||
|
"//tools/analyzers/shadowpredecl:go_default_library",
|
||||||
|
"//tools/analyzers/slicedirect:go_default_library",
|
||||||
"//tools/analyzers/uintcast:go_default_library",
|
"//tools/analyzers/uintcast:go_default_library",
|
||||||
] + select({
|
] + select({
|
||||||
# nogo checks that fail with coverage enabled.
|
# nogo checks that fail with coverage enabled.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://buildkite.com/prysmatic-labs/prysm)
|
[](https://buildkite.com/prysmatic-labs/prysm)
|
||||||
[](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
|
[](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
|
||||||
[](https://github.com/ethereum/consensus-specs/tree/v1.1.8)
|
[](https://github.com/ethereum/consensus-specs/tree/v1.1.10)
|
||||||
[](https://discord.gg/CTYGPUJ)
|
[](https://discord.gg/CTYGPUJ)
|
||||||
|
|
||||||
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/eth2/) specification, developed by [Prysmatic Labs](https://prysmaticlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/eth2/) specification, developed by [Prysmatic Labs](https://prysmaticlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
||||||
|
|||||||
14
WORKSPACE
14
WORKSPACE
@@ -60,10 +60,10 @@ bazel_skylib_workspace()
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "bazel_gazelle",
|
name = "bazel_gazelle",
|
||||||
sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb",
|
sha256 = "5982e5463f171da99e3bdaeff8c0f48283a7a5f396ec5282910b9e8a49c0dd7e",
|
||||||
urls = [
|
urls = [
|
||||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
|
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.25.0/bazel-gazelle-v0.25.0.tar.gz",
|
||||||
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
|
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.25.0/bazel-gazelle-v0.25.0.tar.gz",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,10 +88,10 @@ http_archive(
|
|||||||
# Expose internals of go_test for custom build transitions.
|
# Expose internals of go_test for custom build transitions.
|
||||||
"//third_party:io_bazel_rules_go_test.patch",
|
"//third_party:io_bazel_rules_go_test.patch",
|
||||||
],
|
],
|
||||||
sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
|
sha256 = "f2dcd210c7095febe54b804bb1cd3a58fe8435a909db2ec04e31542631cf715c",
|
||||||
urls = [
|
urls = [
|
||||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
|
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.31.0/rules_go-v0.31.0.zip",
|
||||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
|
"https://github.com/bazelbuild/rules_go/releases/download/v0.31.0/rules_go-v0.31.0.zip",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
|||||||
go_rules_dependencies()
|
go_rules_dependencies()
|
||||||
|
|
||||||
go_register_toolchains(
|
go_register_toolchains(
|
||||||
go_version = "1.17.6",
|
go_version = "1.18.1",
|
||||||
nogo = "@//:nogo",
|
nogo = "@//:nogo",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ go_library(
|
|||||||
"//beacon-chain/core/helpers:go_default_library",
|
"//beacon-chain/core/helpers:go_default_library",
|
||||||
"//beacon-chain/rpc/apimiddleware:go_default_library",
|
"//beacon-chain/rpc/apimiddleware:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//encoding/ssz/detect:go_default_library",
|
"//encoding/ssz/detect:go_default_library",
|
||||||
"//io/file:go_default_library",
|
"//io/file:go_default_library",
|
||||||
"//network/forks:go_default_library",
|
"//network/forks:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@org_golang_x_mod//semver:go_default_library",
|
"@org_golang_x_mod//semver:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -40,15 +40,15 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//encoding/ssz/detect:go_default_library",
|
"//encoding/ssz/detect:go_default_library",
|
||||||
"//network/forks:go_default_library",
|
"//network/forks:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/ssz/detect"
|
"github.com/prysmaticlabs/prysm/encoding/ssz/detect"
|
||||||
"github.com/prysmaticlabs/prysm/io/file"
|
"github.com/prysmaticlabs/prysm/io/file"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -25,7 +25,7 @@ type OriginData struct {
|
|||||||
sb []byte
|
sb []byte
|
||||||
bb []byte
|
bb []byte
|
||||||
st state.BeaconState
|
st state.BeaconState
|
||||||
b block.SignedBeaconBlock
|
b interfaces.SignedBeaconBlock
|
||||||
cf *detect.VersionedUnmarshaler
|
cf *detect.VersionedUnmarshaler
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,15 +40,15 @@ func (od *OriginData) CheckpointString() string {
|
|||||||
// SaveBlock saves the downloaded block to a unique file in the given path.
|
// SaveBlock saves the downloaded block to a unique file in the given path.
|
||||||
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||||
func (od *OriginData) SaveBlock(dir string) (string, error) {
|
func (od *OriginData) SaveBlock(dir string) (string, error) {
|
||||||
blockPath := path.Join(dir, fname("state", od.cf, od.st.Slot(), od.wsd.BlockRoot))
|
blockPath := path.Join(dir, fname("block", od.cf, od.b.Block().Slot(), od.wsd.BlockRoot))
|
||||||
return blockPath, file.WriteFile(blockPath, od.sb)
|
return blockPath, file.WriteFile(blockPath, od.BlockBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveState saves the downloaded state to a unique file in the given path.
|
// SaveState saves the downloaded state to a unique file in the given path.
|
||||||
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||||
func (od *OriginData) SaveState(dir string) (string, error) {
|
func (od *OriginData) SaveState(dir string) (string, error) {
|
||||||
statePath := path.Join(dir, fname("state", od.cf, od.st.Slot(), od.wsd.StateRoot))
|
statePath := path.Join(dir, fname("state", od.cf, od.st.Slot(), od.wsd.StateRoot))
|
||||||
return statePath, file.WriteFile(statePath, od.sb)
|
return statePath, file.WriteFile(statePath, od.StateBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateBytes returns the ssz-encoded bytes of the downloaded BeaconState value.
|
// StateBytes returns the ssz-encoded bytes of the downloaded BeaconState value.
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/network/forks"
|
"github.com/prysmaticlabs/prysm/network/forks"
|
||||||
@@ -17,8 +18,8 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/ssz/detect"
|
"github.com/prysmaticlabs/prysm/encoding/ssz/detect"
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
|
||||||
@@ -66,9 +67,8 @@ func TestMarshalToEnvelope(t *testing.T) {
|
|||||||
|
|
||||||
func TestFallbackVersionCheck(t *testing.T) {
|
func TestFallbackVersionCheck(t *testing.T) {
|
||||||
c := &Client{
|
c := &Client{
|
||||||
hc: &http.Client{},
|
hc: &http.Client{},
|
||||||
host: "localhost:3500",
|
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
|
||||||
scheme: "http",
|
|
||||||
}
|
}
|
||||||
c.hc.Transport = &testRT{rt: func(req *http.Request) (*http.Response, error) {
|
c.hc.Transport = &testRT{rt: func(req *http.Request) (*http.Response, error) {
|
||||||
res := &http.Response{Request: req}
|
res := &http.Response{Request: req}
|
||||||
@@ -200,9 +200,8 @@ func TestDownloadOriginData(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
c := &Client{
|
c := &Client{
|
||||||
hc: hc,
|
hc: hc,
|
||||||
host: "localhost:3500",
|
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
|
||||||
scheme: "http",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
od, err := DownloadOriginData(ctx, c)
|
od, err := DownloadOriginData(ctx, c)
|
||||||
@@ -294,9 +293,8 @@ func TestDownloadBackwardsCompatibleCombined(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
c := &Client{
|
c := &Client{
|
||||||
hc: hc,
|
hc: hc,
|
||||||
host: "localhost:3500",
|
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
|
||||||
scheme: "http",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
odPub, err := DownloadOriginData(ctx, c)
|
odPub, err := DownloadOriginData(ctx, c)
|
||||||
@@ -327,9 +325,8 @@ func TestGetWeakSubjectivityEpochFromHead(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
c := &Client{
|
c := &Client{
|
||||||
hc: hc,
|
hc: hc,
|
||||||
host: "localhost:3500",
|
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
|
||||||
scheme: "http",
|
|
||||||
}
|
}
|
||||||
actualEpoch, err := getWeakSubjectivityEpochFromHead(context.Background(), c)
|
actualEpoch, err := getWeakSubjectivityEpochFromHead(context.Background(), c)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -21,8 +20,8 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware"
|
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -53,6 +52,8 @@ const (
|
|||||||
IdJustified StateOrBlockId = "justified"
|
IdJustified StateOrBlockId = "justified"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrMalformedHostname = errors.New("hostname must include port, separated by one colon, like example.com:3500")
|
||||||
|
|
||||||
// IdFromRoot encodes a block root in the format expected by the API in places where a root can be used to identify
|
// IdFromRoot encodes a block root in the format expected by the API in places where a root can be used to identify
|
||||||
// a BeaconState or SignedBeaconBlock.
|
// a BeaconState or SignedBeaconBlock.
|
||||||
func IdFromRoot(r [32]byte) StateOrBlockId {
|
func IdFromRoot(r [32]byte) StateOrBlockId {
|
||||||
@@ -94,23 +95,23 @@ func WithTimeout(timeout time.Duration) ClientOpt {
|
|||||||
|
|
||||||
// Client provides a collection of helper methods for calling the Eth Beacon Node API endpoints.
|
// Client provides a collection of helper methods for calling the Eth Beacon Node API endpoints.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
hc *http.Client
|
hc *http.Client
|
||||||
host string
|
host string
|
||||||
scheme string
|
scheme string
|
||||||
|
baseURL *url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient constructs a new client with the provided options (ex WithTimeout).
|
// NewClient constructs a new client with the provided options (ex WithTimeout).
|
||||||
// `host` is the base host + port used to construct request urls. This value can be
|
// `host` is the base host + port used to construct request urls. This value can be
|
||||||
// a URL string, or NewClient will assume an http endpoint if just `host:port` is used.
|
// a URL string, or NewClient will assume an http endpoint if just `host:port` is used.
|
||||||
func NewClient(host string, opts ...ClientOpt) (*Client, error) {
|
func NewClient(host string, opts ...ClientOpt) (*Client, error) {
|
||||||
host, err := validHostname(host)
|
u, err := urlForHost(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c := &Client{
|
c := &Client{
|
||||||
hc: &http.Client{},
|
hc: &http.Client{},
|
||||||
scheme: "http",
|
baseURL: u,
|
||||||
host: host,
|
|
||||||
}
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(c)
|
o(c)
|
||||||
@@ -118,36 +119,23 @@ func NewClient(host string, opts ...ClientOpt) (*Client, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validHostname(h string) (string, error) {
|
func urlForHost(h string) (*url.URL, error) {
|
||||||
// try to parse as url (being permissive)
|
// try to parse as url (being permissive)
|
||||||
u, err := url.Parse(h)
|
u, err := url.Parse(h)
|
||||||
if err == nil && u.Host != "" {
|
if err == nil && u.Host != "" {
|
||||||
return u.Host, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
// try to parse as host:port
|
// try to parse as host:port
|
||||||
host, port, err := net.SplitHostPort(h)
|
host, port, err := net.SplitHostPort(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, ErrMalformedHostname
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s:%s", host, port), nil
|
return &url.URL{Host: fmt.Sprintf("%s:%s", host, port), Scheme: "http"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeURL returns a human-readable string representation of the beacon node base url.
|
// NodeURL returns a human-readable string representation of the beacon node base url.
|
||||||
func (c *Client) NodeURL() string {
|
func (c *Client) NodeURL() string {
|
||||||
u := &url.URL{
|
return c.baseURL.String()
|
||||||
Scheme: c.scheme,
|
|
||||||
Host: c.host,
|
|
||||||
}
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) urlForPath(methodPath string) *url.URL {
|
|
||||||
u := &url.URL{
|
|
||||||
Scheme: c.scheme,
|
|
||||||
Host: c.host,
|
|
||||||
}
|
|
||||||
u.Path = path.Join(u.Path, methodPath)
|
|
||||||
return u
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type reqOption func(*http.Request)
|
type reqOption func(*http.Request)
|
||||||
@@ -160,7 +148,7 @@ func withSSZEncoding() reqOption {
|
|||||||
|
|
||||||
// get is a generic, opinionated GET function to reduce boilerplate amongst the getters in this package.
|
// get is a generic, opinionated GET function to reduce boilerplate amongst the getters in this package.
|
||||||
func (c *Client) get(ctx context.Context, path string, opts ...reqOption) ([]byte, error) {
|
func (c *Client) get(ctx context.Context, path string, opts ...reqOption) ([]byte, error) {
|
||||||
u := c.urlForPath(path)
|
u := c.baseURL.ResolveReference(&url.URL{Path: path})
|
||||||
log.Printf("requesting %s", u.String())
|
log.Printf("requesting %s", u.String())
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -273,7 +261,7 @@ type NodeVersion struct {
|
|||||||
systemInfo string
|
systemInfo string
|
||||||
}
|
}
|
||||||
|
|
||||||
var versionRE = regexp.MustCompile(`^(\w+)\/(v\d+\.\d+\.\d+) \((.*)\)$`)
|
var versionRE = regexp.MustCompile(`^(\w+)/(v\d+\.\d+\.\d+[-a-zA-Z0-9]*)\s*/?(.*)$`)
|
||||||
|
|
||||||
func parseNodeVersion(v string) (*NodeVersion, error) {
|
func parseNodeVersion(v string) (*NodeVersion, error) {
|
||||||
groups := versionRE.FindStringSubmatch(v)
|
groups := versionRE.FindStringSubmatch(v)
|
||||||
@@ -369,7 +357,7 @@ type WeakSubjectivityData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func non200Err(response *http.Response) error {
|
func non200Err(response *http.Response) error {
|
||||||
bodyBytes, err := ioutil.ReadAll(response.Body)
|
bodyBytes, err := io.ReadAll(response.Body)
|
||||||
var body string
|
var body string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
body = "(Unable to read response body.)"
|
body = "(Unable to read response body.)"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package beacon
|
package beacon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
@@ -28,18 +29,40 @@ func TestParseNodeVersion(t *testing.T) {
|
|||||||
v: "v2.0.6",
|
v: "v2.0.6",
|
||||||
err: ErrInvalidNodeVersion,
|
err: ErrInvalidNodeVersion,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "implementation and semver only",
|
|
||||||
v: "Prysm/v2.0.6",
|
|
||||||
err: ErrInvalidNodeVersion,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "complete version",
|
name: "complete version",
|
||||||
v: "Prysm/v2.0.6 (linux amd64)",
|
v: "Prysm/v2.0.6 (linux amd64)",
|
||||||
nv: &NodeVersion{
|
nv: &NodeVersion{
|
||||||
implementation: "Prysm",
|
implementation: "Prysm",
|
||||||
semver: "v2.0.6",
|
semver: "v2.0.6",
|
||||||
systemInfo: "linux amd64",
|
systemInfo: "(linux amd64)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nimbus version",
|
||||||
|
v: "Nimbus/v22.4.0-039bec-stateofus",
|
||||||
|
nv: &NodeVersion{
|
||||||
|
implementation: "Nimbus",
|
||||||
|
semver: "v22.4.0-039bec-stateofus",
|
||||||
|
systemInfo: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "teku version",
|
||||||
|
v: "teku/v22.3.2/linux-x86_64/oracle-java-11",
|
||||||
|
nv: &NodeVersion{
|
||||||
|
implementation: "teku",
|
||||||
|
semver: "v22.3.2",
|
||||||
|
systemInfo: "linux-x86_64/oracle-java-11",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lighthouse version",
|
||||||
|
v: "Lighthouse/v2.1.1-5f628a7/x86_64-linux",
|
||||||
|
nv: &NodeVersion{
|
||||||
|
implementation: "Lighthouse",
|
||||||
|
semver: "v2.1.1-5f628a7",
|
||||||
|
systemInfo: "x86_64-linux",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -56,3 +79,60 @@ func TestParseNodeVersion(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidHostname(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
hostArg string
|
||||||
|
path string
|
||||||
|
joined string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "hostname without port",
|
||||||
|
hostArg: "mydomain.org",
|
||||||
|
err: ErrMalformedHostname,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hostname with port",
|
||||||
|
hostArg: "mydomain.org:3500",
|
||||||
|
path: getNodeVersionPath,
|
||||||
|
joined: "http://mydomain.org:3500/eth/v1/node/version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "https scheme, hostname with port",
|
||||||
|
hostArg: "https://mydomain.org:3500",
|
||||||
|
path: getNodeVersionPath,
|
||||||
|
joined: "https://mydomain.org:3500/eth/v1/node/version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http scheme, hostname without port",
|
||||||
|
hostArg: "http://mydomain.org",
|
||||||
|
path: getNodeVersionPath,
|
||||||
|
joined: "http://mydomain.org/eth/v1/node/version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http scheme, trailing slash, hostname without port",
|
||||||
|
hostArg: "http://mydomain.org/",
|
||||||
|
path: getNodeVersionPath,
|
||||||
|
joined: "http://mydomain.org/eth/v1/node/version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http scheme, hostname with basic auth creds and no port",
|
||||||
|
hostArg: "http://username:pass@mydomain.org/",
|
||||||
|
path: getNodeVersionPath,
|
||||||
|
joined: "http://username:pass@mydomain.org/eth/v1/node/version",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
cl, err := NewClient(c.hostArg)
|
||||||
|
if c.err != nil {
|
||||||
|
require.ErrorIs(t, err, c.err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, c.joined, cl.baseURL.ResolveReference(&url.URL{Path: c.path}).String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package apimiddleware
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -73,6 +74,10 @@ func processField(s interface{}, processors []fieldProcessor) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func hexToBase64Processor(v reflect.Value) error {
|
func hexToBase64Processor(v reflect.Value) error {
|
||||||
|
if v.String() == "0x" {
|
||||||
|
v.SetString("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
b, err := bytesutil.FromHexString(v.String())
|
b, err := bytesutil.FromHexString(v.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -83,6 +88,8 @@ func hexToBase64Processor(v reflect.Value) error {
|
|||||||
|
|
||||||
func base64ToHexProcessor(v reflect.Value) error {
|
func base64ToHexProcessor(v reflect.Value) error {
|
||||||
if v.String() == "" {
|
if v.String() == "" {
|
||||||
|
// Empty hex values are represented as "0x".
|
||||||
|
v.SetString("0x")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
b, err := base64.StdEncoding.DecodeString(v.String())
|
b, err := base64.StdEncoding.DecodeString(v.String())
|
||||||
@@ -93,6 +100,55 @@ func base64ToHexProcessor(v reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func base64ToUint256Processor(v reflect.Value) error {
|
||||||
|
if v.String() == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
littleEndian, err := base64.StdEncoding.DecodeString(v.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(littleEndian) != 32 {
|
||||||
|
return errors.New("invalid length for Uint256")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integers are stored as little-endian, but
|
||||||
|
// big.Int expects big-endian. So we need to reverse
|
||||||
|
// the byte order before decoding.
|
||||||
|
var bigEndian [32]byte
|
||||||
|
for i := 0; i < len(littleEndian); i++ {
|
||||||
|
bigEndian[i] = littleEndian[len(littleEndian)-1-i]
|
||||||
|
}
|
||||||
|
var uint256 big.Int
|
||||||
|
uint256.SetBytes(bigEndian[:])
|
||||||
|
v.SetString(uint256.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint256ToBase64Processor(v reflect.Value) error {
|
||||||
|
if v.String() == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
uint256, ok := new(big.Int).SetString(v.String(), 10)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("could not parse Uint256")
|
||||||
|
}
|
||||||
|
bigEndian := uint256.Bytes()
|
||||||
|
if len(bigEndian) > 32 {
|
||||||
|
return fmt.Errorf("number too big for Uint256")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integers are stored as little-endian, but
|
||||||
|
// big.Int gives big-endian. So we need to reverse
|
||||||
|
// the byte order before encoding.
|
||||||
|
var littleEndian [32]byte
|
||||||
|
for i := 0; i < len(bigEndian); i++ {
|
||||||
|
littleEndian[i] = bigEndian[len(bigEndian)-1-i]
|
||||||
|
}
|
||||||
|
v.SetString(base64.StdEncoding.EncodeToString(littleEndian[:]))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func enumToLowercaseProcessor(v reflect.Value) error {
|
func enumToLowercaseProcessor(v reflect.Value) error {
|
||||||
v.SetString(strings.ToLower(v.String()))
|
v.SetString(strings.ToLower(v.String()))
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -38,6 +37,10 @@ func ProcessRequestContainerFields(requestContainer interface{}) ErrorJson {
|
|||||||
tag: "hex",
|
tag: "hex",
|
||||||
f: hexToBase64Processor,
|
f: hexToBase64Processor,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
tag: "uint256",
|
||||||
|
f: uint256ToBase64Processor,
|
||||||
|
},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return InternalServerErrorWithMessage(err, "could not process request data")
|
return InternalServerErrorWithMessage(err, "could not process request data")
|
||||||
}
|
}
|
||||||
@@ -52,7 +55,7 @@ func SetRequestBodyToRequestContainer(requestContainer interface{}, req *http.Re
|
|||||||
return InternalServerErrorWithMessage(err, "could not marshal request")
|
return InternalServerErrorWithMessage(err, "could not marshal request")
|
||||||
}
|
}
|
||||||
// Set the body to the new JSON.
|
// Set the body to the new JSON.
|
||||||
req.Body = ioutil.NopCloser(bytes.NewReader(j))
|
req.Body = io.NopCloser(bytes.NewReader(j))
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(j)))
|
req.Header.Set("Content-Length", strconv.Itoa(len(j)))
|
||||||
req.ContentLength = int64(len(j))
|
req.ContentLength = int64(len(j))
|
||||||
return nil
|
return nil
|
||||||
@@ -93,7 +96,7 @@ func (m *ApiProxyMiddleware) ProxyRequest(req *http.Request) (*http.Response, Er
|
|||||||
|
|
||||||
// ReadGrpcResponseBody reads the body from the grpc-gateway's response.
|
// ReadGrpcResponseBody reads the body from the grpc-gateway's response.
|
||||||
func ReadGrpcResponseBody(r io.Reader) ([]byte, ErrorJson) {
|
func ReadGrpcResponseBody(r io.Reader) ([]byte, ErrorJson) {
|
||||||
body, err := ioutil.ReadAll(r)
|
body, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, InternalServerErrorWithMessage(err, "could not read response body")
|
return nil, InternalServerErrorWithMessage(err, "could not read response body")
|
||||||
}
|
}
|
||||||
@@ -154,6 +157,10 @@ func ProcessMiddlewareResponseFields(responseContainer interface{}) ErrorJson {
|
|||||||
tag: "time",
|
tag: "time",
|
||||||
f: timeToUnixProcessor,
|
f: timeToUnixProcessor,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
tag: "uint256",
|
||||||
|
f: base64ToUint256Processor,
|
||||||
|
},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return InternalServerErrorWithMessage(err, "could not process response data")
|
return InternalServerErrorWithMessage(err, "could not process response data")
|
||||||
}
|
}
|
||||||
@@ -195,7 +202,7 @@ func WriteMiddlewareResponseHeadersAndBody(grpcResp *http.Response, responseJson
|
|||||||
} else {
|
} else {
|
||||||
w.WriteHeader(grpcResp.StatusCode)
|
w.WriteHeader(grpcResp.StatusCode)
|
||||||
}
|
}
|
||||||
if _, err := io.Copy(w, ioutil.NopCloser(bytes.NewReader(responseJson))); err != nil {
|
if _, err := io.Copy(w, io.NopCloser(bytes.NewReader(responseJson))); err != nil {
|
||||||
return InternalServerErrorWithMessage(err, "could not write response message")
|
return InternalServerErrorWithMessage(err, "could not write response message")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -249,7 +256,7 @@ func WriteError(w http.ResponseWriter, errJson ErrorJson, responseHeader http.He
|
|||||||
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
|
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(errJson.StatusCode())
|
w.WriteHeader(errJson.StatusCode())
|
||||||
if _, err := io.Copy(w, ioutil.NopCloser(bytes.NewReader(j))); err != nil {
|
if _, err := io.Copy(w, io.NopCloser(bytes.NewReader(j))); err != nil {
|
||||||
log.WithError(err).Error("Could not write error message")
|
log.WithError(err).Error("Could not write error message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,30 +15,40 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type testRequestContainer struct {
|
type testRequestContainer struct {
|
||||||
TestString string
|
TestString string
|
||||||
TestHexString string `hex:"true"`
|
TestHexString string `hex:"true"`
|
||||||
|
TestEmptyHexString string `hex:"true"`
|
||||||
|
TestUint256String string `uint256:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultRequestContainer() *testRequestContainer {
|
func defaultRequestContainer() *testRequestContainer {
|
||||||
return &testRequestContainer{
|
return &testRequestContainer{
|
||||||
TestString: "test string",
|
TestString: "test string",
|
||||||
TestHexString: "0x666F6F", // hex encoding of "foo"
|
TestHexString: "0x666F6F", // hex encoding of "foo"
|
||||||
|
TestEmptyHexString: "0x",
|
||||||
|
TestUint256String: "4196",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type testResponseContainer struct {
|
type testResponseContainer struct {
|
||||||
TestString string
|
TestString string
|
||||||
TestHex string `hex:"true"`
|
TestHex string `hex:"true"`
|
||||||
TestEnum string `enum:"true"`
|
TestEmptyHex string `hex:"true"`
|
||||||
TestTime string `time:"true"`
|
TestUint256 string `uint256:"true"`
|
||||||
|
TestEnum string `enum:"true"`
|
||||||
|
TestTime string `time:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultResponseContainer() *testResponseContainer {
|
func defaultResponseContainer() *testResponseContainer {
|
||||||
return &testResponseContainer{
|
return &testResponseContainer{
|
||||||
TestString: "test string",
|
TestString: "test string",
|
||||||
TestHex: "Zm9v", // base64 encoding of "foo"
|
TestHex: "Zm9v", // base64 encoding of "foo"
|
||||||
TestEnum: "Test Enum",
|
TestEmptyHex: "",
|
||||||
TestTime: "2006-01-02T15:04:05Z",
|
TestEnum: "Test Enum",
|
||||||
|
TestTime: "2006-01-02T15:04:05Z",
|
||||||
|
|
||||||
|
// base64 encoding of 4196 in little-endian
|
||||||
|
TestUint256: "ZBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +116,8 @@ func TestProcessRequestContainerFields(t *testing.T) {
|
|||||||
errJson := ProcessRequestContainerFields(container)
|
errJson := ProcessRequestContainerFields(container)
|
||||||
require.Equal(t, true, errJson == nil)
|
require.Equal(t, true, errJson == nil)
|
||||||
assert.Equal(t, "Zm9v", container.TestHexString)
|
assert.Equal(t, "Zm9v", container.TestHexString)
|
||||||
|
assert.Equal(t, "", container.TestEmptyHexString)
|
||||||
|
assert.Equal(t, "ZBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", container.TestUint256String)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("error", func(t *testing.T) {
|
t.Run("error", func(t *testing.T) {
|
||||||
@@ -128,8 +140,8 @@ func TestSetRequestBodyToRequestContainer(t *testing.T) {
|
|||||||
contentLengthHeader, ok := request.Header["Content-Length"]
|
contentLengthHeader, ok := request.Header["Content-Length"]
|
||||||
require.Equal(t, true, ok)
|
require.Equal(t, true, ok)
|
||||||
require.Equal(t, 1, len(contentLengthHeader), "wrong number of header values")
|
require.Equal(t, 1, len(contentLengthHeader), "wrong number of header values")
|
||||||
assert.Equal(t, "55", contentLengthHeader[0])
|
assert.Equal(t, "108", contentLengthHeader[0])
|
||||||
assert.Equal(t, int64(55), request.ContentLength)
|
assert.Equal(t, int64(108), request.ContentLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrepareRequestForProxying(t *testing.T) {
|
func TestPrepareRequestForProxying(t *testing.T) {
|
||||||
@@ -234,6 +246,8 @@ func TestProcessMiddlewareResponseFields(t *testing.T) {
|
|||||||
errJson := ProcessMiddlewareResponseFields(container)
|
errJson := ProcessMiddlewareResponseFields(container)
|
||||||
require.Equal(t, true, errJson == nil)
|
require.Equal(t, true, errJson == nil)
|
||||||
assert.Equal(t, "0x666f6f", container.TestHex)
|
assert.Equal(t, "0x666f6f", container.TestHex)
|
||||||
|
assert.Equal(t, "0x", container.TestEmptyHex)
|
||||||
|
assert.Equal(t, "4196", container.TestUint256)
|
||||||
assert.Equal(t, "test enum", container.TestEnum)
|
assert.Equal(t, "test enum", container.TestEnum)
|
||||||
assert.Equal(t, "1136214245", container.TestTime)
|
assert.Equal(t, "1136214245", container.TestTime)
|
||||||
})
|
})
|
||||||
@@ -278,7 +292,7 @@ func TestWriteMiddlewareResponseHeadersAndBody(t *testing.T) {
|
|||||||
v, ok = writer.Header()["Content-Length"]
|
v, ok = writer.Header()["Content-Length"]
|
||||||
require.Equal(t, true, ok, "header not found")
|
require.Equal(t, true, ok, "header not found")
|
||||||
require.Equal(t, 1, len(v), "wrong number of header values")
|
require.Equal(t, 1, len(v), "wrong number of header values")
|
||||||
assert.Equal(t, "102", v[0])
|
assert.Equal(t, "181", v[0])
|
||||||
assert.Equal(t, 204, writer.Code)
|
assert.Equal(t, 204, writer.Code)
|
||||||
assert.DeepEqual(t, responseJson, writer.Body.Bytes())
|
assert.DeepEqual(t, responseJson, writer.Body.Bytes())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"chain_info.go",
|
"chain_info.go",
|
||||||
"error.go",
|
"error.go",
|
||||||
|
"execution_engine.go",
|
||||||
"head.go",
|
"head.go",
|
||||||
"head_sync_committee_info.go",
|
"head_sync_committee_info.go",
|
||||||
"init_sync_process_block.go",
|
"init_sync_process_block.go",
|
||||||
"log.go",
|
"log.go",
|
||||||
"metrics.go",
|
"metrics.go",
|
||||||
"new_slot.go",
|
"new_slot.go",
|
||||||
"optimistic_sync.go",
|
|
||||||
"options.go",
|
"options.go",
|
||||||
"pow_block.go",
|
"pow_block.go",
|
||||||
"process_attestation.go",
|
"process_attestation.go",
|
||||||
@@ -64,14 +64,16 @@ go_library(
|
|||||||
"//config/features:go_default_library",
|
"//config/features:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//math:go_default_library",
|
||||||
"//monitoring/tracing:go_default_library",
|
"//monitoring/tracing:go_default_library",
|
||||||
"//proto/engine/v1:go_default_library",
|
"//proto/engine/v1:go_default_library",
|
||||||
"//proto/eth/v1:go_default_library",
|
"//proto/eth/v1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//time:go_default_library",
|
"//time:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
@@ -81,7 +83,6 @@ go_library(
|
|||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -102,13 +103,13 @@ go_test(
|
|||||||
"blockchain_test.go",
|
"blockchain_test.go",
|
||||||
"chain_info_test.go",
|
"chain_info_test.go",
|
||||||
"checktags_test.go",
|
"checktags_test.go",
|
||||||
|
"execution_engine_test.go",
|
||||||
"head_sync_committee_info_test.go",
|
"head_sync_committee_info_test.go",
|
||||||
"head_test.go",
|
"head_test.go",
|
||||||
"init_test.go",
|
"init_test.go",
|
||||||
"log_test.go",
|
"log_test.go",
|
||||||
"metrics_test.go",
|
"metrics_test.go",
|
||||||
"mock_test.go",
|
"mock_test.go",
|
||||||
"optimistic_sync_test.go",
|
|
||||||
"pow_block_test.go",
|
"pow_block_test.go",
|
||||||
"process_attestation_test.go",
|
"process_attestation_test.go",
|
||||||
"process_block_test.go",
|
"process_block_test.go",
|
||||||
@@ -135,9 +136,9 @@ go_test(
|
|||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
@@ -186,9 +187,9 @@ go_test(
|
|||||||
"//beacon-chain/powchain:go_default_library",
|
"//beacon-chain/powchain:go_default_library",
|
||||||
"//beacon-chain/powchain/testing:go_default_library",
|
"//beacon-chain/powchain/testing:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package blockchain
|
package blockchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
logrus.SetLevel(logrus.DebugLevel)
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
logrus.SetOutput(ioutil.Discard)
|
logrus.SetOutput(io.Discard)
|
||||||
|
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
@@ -12,9 +11,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
@@ -31,6 +31,12 @@ type ChainInfoFetcher interface {
|
|||||||
HeadDomainFetcher
|
HeadDomainFetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeadUpdater defines a common interface for methods in blockchain service
|
||||||
|
// which allow to update the head info
|
||||||
|
type HeadUpdater interface {
|
||||||
|
UpdateHead(context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
// TimeFetcher retrieves the Ethereum consensus data that's related to time.
|
// TimeFetcher retrieves the Ethereum consensus data that's related to time.
|
||||||
type TimeFetcher interface {
|
type TimeFetcher interface {
|
||||||
GenesisTime() time.Time
|
GenesisTime() time.Time
|
||||||
@@ -47,10 +53,9 @@ type GenesisFetcher interface {
|
|||||||
type HeadFetcher interface {
|
type HeadFetcher interface {
|
||||||
HeadSlot() types.Slot
|
HeadSlot() types.Slot
|
||||||
HeadRoot(ctx context.Context) ([]byte, error)
|
HeadRoot(ctx context.Context) ([]byte, error)
|
||||||
HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error)
|
HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
|
||||||
HeadState(ctx context.Context) (state.BeaconState, error)
|
HeadState(ctx context.Context) (state.BeaconState, error)
|
||||||
HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error)
|
HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error)
|
||||||
HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error)
|
|
||||||
HeadGenesisValidatorsRoot() [32]byte
|
HeadGenesisValidatorsRoot() [32]byte
|
||||||
HeadETH1Data() *ethpb.Eth1Data
|
HeadETH1Data() *ethpb.Eth1Data
|
||||||
HeadPublicKeyToValidatorIndex(pubKey [fieldparams.BLSPubkeyLength]byte) (types.ValidatorIndex, bool)
|
HeadPublicKeyToValidatorIndex(pubKey [fieldparams.BLSPubkeyLength]byte) (types.ValidatorIndex, bool)
|
||||||
@@ -60,18 +65,17 @@ type HeadFetcher interface {
|
|||||||
IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool, error)
|
IsOptimisticForRoot(ctx context.Context, root [32]byte) (bool, error)
|
||||||
HeadSyncCommitteeFetcher
|
HeadSyncCommitteeFetcher
|
||||||
HeadDomainFetcher
|
HeadDomainFetcher
|
||||||
ForkChoicer() forkchoice.ForkChoicer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForkFetcher retrieves the current fork information of the Ethereum beacon chain.
|
// ForkFetcher retrieves the current fork information of the Ethereum beacon chain.
|
||||||
type ForkFetcher interface {
|
type ForkFetcher interface {
|
||||||
|
ForkChoicer() forkchoice.ForkChoicer
|
||||||
CurrentFork() *ethpb.Fork
|
CurrentFork() *ethpb.Fork
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalFetcher retrieves the current chain's canonical information.
|
// CanonicalFetcher retrieves the current chain's canonical information.
|
||||||
type CanonicalFetcher interface {
|
type CanonicalFetcher interface {
|
||||||
IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error)
|
IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error)
|
||||||
VerifyBlkDescendant(ctx context.Context, blockRoot [32]byte) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalizationFetcher defines a common interface for methods in blockchain service which
|
// FinalizationFetcher defines a common interface for methods in blockchain service which
|
||||||
@@ -80,6 +84,7 @@ type FinalizationFetcher interface {
|
|||||||
FinalizedCheckpt() *ethpb.Checkpoint
|
FinalizedCheckpt() *ethpb.Checkpoint
|
||||||
CurrentJustifiedCheckpt() *ethpb.Checkpoint
|
CurrentJustifiedCheckpt() *ethpb.Checkpoint
|
||||||
PreviousJustifiedCheckpt() *ethpb.Checkpoint
|
PreviousJustifiedCheckpt() *ethpb.Checkpoint
|
||||||
|
VerifyFinalizedBlkDescendant(ctx context.Context, blockRoot [32]byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalizedCheckpt returns the latest finalized checkpoint from chain store.
|
// FinalizedCheckpt returns the latest finalized checkpoint from chain store.
|
||||||
@@ -164,7 +169,7 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
|
|||||||
// HeadBlock returns the head block of the chain.
|
// HeadBlock returns the head block of the chain.
|
||||||
// If the head is nil from service struct,
|
// If the head is nil from service struct,
|
||||||
// it will attempt to get the head block from DB.
|
// it will attempt to get the head block from DB.
|
||||||
func (s *Service) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
|
func (s *Service) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
|
||||||
s.headLock.RLock()
|
s.headLock.RLock()
|
||||||
defer s.headLock.RUnlock()
|
defer s.headLock.RUnlock()
|
||||||
|
|
||||||
@@ -205,18 +210,6 @@ func (s *Service) HeadValidatorsIndices(ctx context.Context, epoch types.Epoch)
|
|||||||
return helpers.ActiveValidatorIndices(ctx, s.headState(ctx), epoch)
|
return helpers.ActiveValidatorIndices(ctx, s.headState(ctx), epoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadSeed returns the seed from the head view of a given epoch.
|
|
||||||
func (s *Service) HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error) {
|
|
||||||
s.headLock.RLock()
|
|
||||||
defer s.headLock.RUnlock()
|
|
||||||
|
|
||||||
if !s.hasHeadState() {
|
|
||||||
return [32]byte{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return helpers.Seed(s.headState(ctx), epoch, params.BeaconConfig().DomainBeaconAttester)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HeadGenesisValidatorsRoot returns genesis validators root of the head state.
|
// HeadGenesisValidatorsRoot returns genesis validators root of the head state.
|
||||||
func (s *Service) HeadGenesisValidatorsRoot() [32]byte {
|
func (s *Service) HeadGenesisValidatorsRoot() [32]byte {
|
||||||
s.headLock.RLock()
|
s.headLock.RLock()
|
||||||
@@ -273,13 +266,13 @@ func (s *Service) CurrentFork() *ethpb.Fork {
|
|||||||
|
|
||||||
// IsCanonical returns true if the input block root is part of the canonical chain.
|
// 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) {
|
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 the block has not been finalized, check fork choice store to see if the block is canonical
|
||||||
if s.cfg.BeaconDB.IsFinalizedBlock(ctx, blockRoot) {
|
if s.cfg.ForkChoiceStore.HasNode(blockRoot) {
|
||||||
return true, nil
|
return s.cfg.ForkChoiceStore.IsCanonical(blockRoot), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the block has not been finalized, check fork choice store to see if the block is canonical
|
// If the block has been finalized, the block will always be part of the canonical chain.
|
||||||
return s.cfg.ForkChoiceStore.IsCanonical(blockRoot), nil
|
return s.cfg.BeaconDB.IsFinalizedBlock(ctx, blockRoot), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainHeads returns all possible chain heads (leaves of fork choice tree).
|
// ChainHeads returns all possible chain heads (leaves of fork choice tree).
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,17 +5,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -52,7 +51,7 @@ func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
|
|||||||
|
|
||||||
cp := ðpb.Checkpoint{Epoch: 5, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
cp := ðpb.Checkpoint{Epoch: 5, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
||||||
c := setupBeaconChain(t, beaconDB)
|
c := setupBeaconChain(t, beaconDB)
|
||||||
c.store.SetFinalizedCheckpt(cp)
|
c.store.SetFinalizedCheckptAndPayloadHash(cp, [32]byte{'a'})
|
||||||
|
|
||||||
assert.Equal(t, cp.Epoch, c.FinalizedCheckpt().Epoch, "Unexpected finalized epoch")
|
assert.Equal(t, cp.Epoch, c.FinalizedCheckpt().Epoch, "Unexpected finalized epoch")
|
||||||
}
|
}
|
||||||
@@ -63,7 +62,7 @@ func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
|
|||||||
genesisRoot := [32]byte{'A'}
|
genesisRoot := [32]byte{'A'}
|
||||||
cp := ðpb.Checkpoint{Root: genesisRoot[:]}
|
cp := ðpb.Checkpoint{Root: genesisRoot[:]}
|
||||||
c := setupBeaconChain(t, beaconDB)
|
c := setupBeaconChain(t, beaconDB)
|
||||||
c.store.SetFinalizedCheckpt(cp)
|
c.store.SetFinalizedCheckptAndPayloadHash(cp, [32]byte{'a'})
|
||||||
c.originBlockRoot = genesisRoot
|
c.originBlockRoot = genesisRoot
|
||||||
assert.DeepEqual(t, c.originBlockRoot[:], c.FinalizedCheckpt().Root)
|
assert.DeepEqual(t, c.originBlockRoot[:], c.FinalizedCheckpt().Root)
|
||||||
}
|
}
|
||||||
@@ -74,7 +73,7 @@ func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
|
|||||||
c := setupBeaconChain(t, beaconDB)
|
c := setupBeaconChain(t, beaconDB)
|
||||||
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
|
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
|
||||||
cp := ðpb.Checkpoint{Epoch: 6, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
cp := ðpb.Checkpoint{Epoch: 6, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
||||||
c.store.SetJustifiedCheckpt(cp)
|
c.store.SetJustifiedCheckptAndPayloadHash(cp, [32]byte{})
|
||||||
assert.Equal(t, cp.Epoch, c.CurrentJustifiedCheckpt().Epoch, "Unexpected justified epoch")
|
assert.Equal(t, cp.Epoch, c.CurrentJustifiedCheckpt().Epoch, "Unexpected justified epoch")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +83,7 @@ func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
|
|||||||
c := setupBeaconChain(t, beaconDB)
|
c := setupBeaconChain(t, beaconDB)
|
||||||
genesisRoot := [32]byte{'B'}
|
genesisRoot := [32]byte{'B'}
|
||||||
cp := ðpb.Checkpoint{Root: genesisRoot[:]}
|
cp := ðpb.Checkpoint{Root: genesisRoot[:]}
|
||||||
c.store.SetJustifiedCheckpt(cp)
|
c.store.SetJustifiedCheckptAndPayloadHash(cp, [32]byte{})
|
||||||
c.originBlockRoot = genesisRoot
|
c.originBlockRoot = genesisRoot
|
||||||
assert.DeepEqual(t, c.originBlockRoot[:], c.CurrentJustifiedCheckpt().Root)
|
assert.DeepEqual(t, c.originBlockRoot[:], c.CurrentJustifiedCheckpt().Root)
|
||||||
}
|
}
|
||||||
@@ -261,23 +260,6 @@ func TestService_HeadValidatorsIndices(t *testing.T) {
|
|||||||
require.Equal(t, 10, len(indices))
|
require.Equal(t, 10, len(indices))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_HeadSeed(t *testing.T) {
|
|
||||||
s, _ := util.DeterministicGenesisState(t, 1)
|
|
||||||
c := &Service{}
|
|
||||||
seed, err := helpers.Seed(s, 0, params.BeaconConfig().DomainBeaconAttester)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
c.head = &head{}
|
|
||||||
root, err := c.HeadSeed(context.Background(), 0)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, [32]byte{}, root)
|
|
||||||
|
|
||||||
c.head = &head{state: s}
|
|
||||||
root, err = c.HeadSeed(context.Background(), 0)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.DeepEqual(t, seed, root)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestService_HeadGenesisValidatorsRoot(t *testing.T) {
|
func TestService_HeadGenesisValidatorsRoot(t *testing.T) {
|
||||||
s, _ := util.DeterministicGenesisState(t, 1)
|
s, _ := util.DeterministicGenesisState(t, 1)
|
||||||
c := &Service{}
|
c := &Service{}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
@@ -15,22 +14,36 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidPayload = errors.New("recevied an INVALID payload from execution engine")
|
||||||
|
ErrUndefinedExecutionEngineError = errors.New("received an undefined ee error")
|
||||||
|
)
|
||||||
|
|
||||||
|
// notifyForkchoiceUpdateArg is the argument for the forkchoice update notification `notifyForkchoiceUpdate`.
|
||||||
|
type notifyForkchoiceUpdateArg struct {
|
||||||
|
headState state.BeaconState
|
||||||
|
headRoot [32]byte
|
||||||
|
headBlock interfaces.BeaconBlock
|
||||||
|
}
|
||||||
|
|
||||||
// notifyForkchoiceUpdate signals execution engine the fork choice updates. Execution engine should:
|
// notifyForkchoiceUpdate signals execution engine the fork choice updates. Execution engine should:
|
||||||
// 1. Re-organizes the execution payload chain and corresponding state to make head_block_hash the head.
|
// 1. Re-organizes the execution payload chain and corresponding state to make head_block_hash the head.
|
||||||
// 2. Applies finality to the execution state: it irreversibly persists the chain of all execution payloads and corresponding state, up to and including finalized_block_hash.
|
// 2. Applies finality to the execution state: it irreversibly persists the chain of all execution payloads and corresponding state, up to and including finalized_block_hash.
|
||||||
func (s *Service) notifyForkchoiceUpdate(ctx context.Context, headState state.BeaconState, headBlk block.BeaconBlock, headRoot [32]byte, finalizedRoot [32]byte) (*enginev1.PayloadIDBytes, error) {
|
func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkchoiceUpdateArg) (*enginev1.PayloadIDBytes, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.notifyForkchoiceUpdate")
|
ctx, span := trace.StartSpan(ctx, "blockChain.notifyForkchoiceUpdate")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
headBlk := arg.headBlock
|
||||||
if headBlk == nil || headBlk.IsNil() || headBlk.Body().IsNil() {
|
if headBlk == nil || headBlk.IsNil() || headBlk.Body().IsNil() {
|
||||||
return nil, errors.New("nil head block")
|
return nil, errors.New("nil head block")
|
||||||
}
|
}
|
||||||
@@ -46,54 +59,76 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, headState state.Be
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get execution payload")
|
return nil, errors.Wrap(err, "could not get execution payload")
|
||||||
}
|
}
|
||||||
finalizedBlock, err := s.cfg.BeaconDB.Block(ctx, s.ensureRootNotZeros(finalizedRoot))
|
finalizedHash := s.store.FinalizedPayloadBlockHash()
|
||||||
if err != nil {
|
justifiedHash := s.store.JustifiedPayloadBlockHash()
|
||||||
return nil, errors.Wrap(err, "could not get finalized block")
|
|
||||||
}
|
|
||||||
if finalizedBlock == nil || finalizedBlock.IsNil() {
|
|
||||||
finalizedBlock = s.getInitSyncBlock(s.ensureRootNotZeros(finalizedRoot))
|
|
||||||
if finalizedBlock == nil || finalizedBlock.IsNil() {
|
|
||||||
return nil, errors.Errorf("finalized block with root %#x does not exist in the db or our cache", s.ensureRootNotZeros(finalizedRoot))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var finalizedHash []byte
|
|
||||||
if blocks.IsPreBellatrixVersion(finalizedBlock.Block().Version()) {
|
|
||||||
finalizedHash = params.BeaconConfig().ZeroHash[:]
|
|
||||||
} else {
|
|
||||||
payload, err := finalizedBlock.Block().Body().ExecutionPayload()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not get finalized block execution payload")
|
|
||||||
}
|
|
||||||
finalizedHash = payload.BlockHash
|
|
||||||
}
|
|
||||||
|
|
||||||
fcs := &enginev1.ForkchoiceState{
|
fcs := &enginev1.ForkchoiceState{
|
||||||
HeadBlockHash: headPayload.BlockHash,
|
HeadBlockHash: headPayload.BlockHash,
|
||||||
SafeBlockHash: headPayload.BlockHash,
|
SafeBlockHash: justifiedHash[:],
|
||||||
FinalizedBlockHash: finalizedHash,
|
FinalizedBlockHash: finalizedHash[:],
|
||||||
}
|
}
|
||||||
|
|
||||||
nextSlot := s.CurrentSlot() + 1 // Cache payload ID for next slot proposer.
|
nextSlot := s.CurrentSlot() + 1 // Cache payload ID for next slot proposer.
|
||||||
hasAttr, attr, proposerId, err := s.getPayloadAttribute(ctx, headState, nextSlot)
|
hasAttr, attr, proposerId, err := s.getPayloadAttribute(ctx, arg.headState, nextSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get payload attribute")
|
return nil, errors.Wrap(err, "could not get payload attribute")
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadID, _, err := s.cfg.ExecutionEngineCaller.ForkchoiceUpdated(ctx, fcs, attr)
|
payloadID, lastValidHash, err := s.cfg.ExecutionEngineCaller.ForkchoiceUpdated(ctx, fcs, attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
case powchain.ErrAcceptedSyncingPayloadStatus:
|
case powchain.ErrAcceptedSyncingPayloadStatus:
|
||||||
|
forkchoiceUpdatedOptimisticNodeCount.Inc()
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"headSlot": headBlk.Slot(),
|
"headSlot": headBlk.Slot(),
|
||||||
"headHash": fmt.Sprintf("%#x", bytesutil.Trunc(headPayload.BlockHash)),
|
"headPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(headPayload.BlockHash)),
|
||||||
"finalizedHash": fmt.Sprintf("%#x", bytesutil.Trunc(finalizedHash)),
|
"finalizedPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(finalizedHash[:])),
|
||||||
}).Info("Called fork choice updated with optimistic block")
|
}).Info("Called fork choice updated with optimistic block")
|
||||||
return payloadID, nil
|
return payloadID, s.optimisticCandidateBlock(ctx, headBlk)
|
||||||
|
case powchain.ErrInvalidPayloadStatus:
|
||||||
|
newPayloadInvalidNodeCount.Inc()
|
||||||
|
headRoot := arg.headRoot
|
||||||
|
invalidRoots, err := s.ForkChoicer().SetOptimisticToInvalid(ctx, headRoot, bytesutil.ToBytes32(headBlk.ParentRoot()), bytesutil.ToBytes32(lastValidHash))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := s.removeInvalidBlockAndState(ctx, invalidRoots); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := s.updateHead(ctx, s.justifiedBalances.balances)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b, err := s.getBlock(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st, err := s.cfg.StateGen.StateByRoot(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pid, err := s.notifyForkchoiceUpdate(ctx, ¬ifyForkchoiceUpdateArg{
|
||||||
|
headState: st,
|
||||||
|
headRoot: r,
|
||||||
|
headBlock: b.Block(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"slot": headBlk.Slot(),
|
||||||
|
"blockRoot": fmt.Sprintf("%#x", headRoot),
|
||||||
|
"invalidCount": len(invalidRoots),
|
||||||
|
}).Warn("Pruned invalid blocks")
|
||||||
|
return pid, ErrInvalidPayload
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.Wrap(err, "could not notify forkchoice update from execution engine")
|
return nil, errors.WithMessage(ErrUndefinedExecutionEngineError, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, headRoot); err != nil {
|
forkchoiceUpdatedValidNodeCount.Inc()
|
||||||
|
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, arg.headRoot); err != nil {
|
||||||
return nil, errors.Wrap(err, "could not set block to valid")
|
return nil, errors.Wrap(err, "could not set block to valid")
|
||||||
}
|
}
|
||||||
if hasAttr { // If the forkchoice update call has an attribute, update the proposer payload ID cache.
|
if hasAttr { // If the forkchoice update call has an attribute, update the proposer payload ID cache.
|
||||||
@@ -104,10 +139,27 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, headState state.Be
|
|||||||
return payloadID, nil
|
return payloadID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPayloadHash returns the payload hash given the block root.
|
||||||
|
// if the block is before bellatrix fork epoch, it returns the zero hash.
|
||||||
|
func (s *Service) getPayloadHash(ctx context.Context, root []byte) ([32]byte, error) {
|
||||||
|
blk, err := s.getBlock(ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(root)))
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
if blocks.IsPreBellatrixVersion(blk.Block().Version()) {
|
||||||
|
return params.BeaconConfig().ZeroHash, nil
|
||||||
|
}
|
||||||
|
payload, err := blk.Block().Body().ExecutionPayload()
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, errors.Wrap(err, "could not get execution payload")
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes32(payload.BlockHash), nil
|
||||||
|
}
|
||||||
|
|
||||||
// notifyForkchoiceUpdate signals execution engine on a new payload.
|
// notifyForkchoiceUpdate signals execution engine on a new payload.
|
||||||
// It returns true if the EL has returned VALID for the block
|
// It returns true if the EL has returned VALID for the block
|
||||||
func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion, postStateVersion int,
|
func (s *Service) notifyNewPayload(ctx context.Context, postStateVersion int,
|
||||||
preStateHeader, postStateHeader *ethpb.ExecutionPayloadHeader, blk block.SignedBeaconBlock) (bool, error) {
|
postStateHeader *ethpb.ExecutionPayloadHeader, blk interfaces.SignedBeaconBlock) (bool, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.notifyNewPayload")
|
ctx, span := trace.StartSpan(ctx, "blockChain.notifyNewPayload")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -132,49 +184,43 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion, postSta
|
|||||||
return false, errors.Wrap(err, "could not get execution payload")
|
return false, errors.Wrap(err, "could not get execution payload")
|
||||||
}
|
}
|
||||||
lastValidHash, err := s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload)
|
lastValidHash, err := s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload)
|
||||||
if err != nil {
|
switch err {
|
||||||
switch err {
|
case nil:
|
||||||
case powchain.ErrAcceptedSyncingPayloadStatus:
|
newPayloadValidNodeCount.Inc()
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"slot": blk.Block().Slot(),
|
|
||||||
"blockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash)),
|
|
||||||
}).Info("Called new payload with optimistic block")
|
|
||||||
return false, nil
|
|
||||||
case powchain.ErrInvalidPayloadStatus:
|
|
||||||
root, err := blk.Block().HashTreeRoot()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
invalidRoots, err := s.ForkChoicer().SetOptimisticToInvalid(ctx, root, bytesutil.ToBytes32(lastValidHash))
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if err := s.removeInvalidBlockAndState(ctx, invalidRoots); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, errors.New("could not validate an INVALID payload from execution engine")
|
|
||||||
default:
|
|
||||||
return false, errors.Wrap(err, "could not validate execution payload from execution engine")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// During the transition event, the transition block should be verified for sanity.
|
|
||||||
if blocks.IsPreBellatrixVersion(preStateVersion) {
|
|
||||||
// Handle case where pre-state is Altair but block contains payload.
|
|
||||||
// To reach here, the block must have contained a valid payload.
|
|
||||||
return true, s.validateMergeBlock(ctx, blk)
|
|
||||||
}
|
|
||||||
atTransition, err := blocks.IsMergeTransitionBlockUsingPreStatePayloadHeader(preStateHeader, body)
|
|
||||||
if err != nil {
|
|
||||||
return true, errors.Wrap(err, "could not check if merge block is terminal")
|
|
||||||
}
|
|
||||||
if !atTransition {
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
case powchain.ErrAcceptedSyncingPayloadStatus:
|
||||||
|
newPayloadOptimisticNodeCount.Inc()
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"slot": blk.Block().Slot(),
|
||||||
|
"payloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash)),
|
||||||
|
}).Info("Called new payload with optimistic block")
|
||||||
|
return false, s.optimisticCandidateBlock(ctx, blk.Block())
|
||||||
|
case powchain.ErrInvalidPayloadStatus:
|
||||||
|
newPayloadInvalidNodeCount.Inc()
|
||||||
|
root, err := blk.Block().HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
invalidRoots, err := s.ForkChoicer().SetOptimisticToInvalid(ctx, root, bytesutil.ToBytes32(blk.Block().ParentRoot()), bytesutil.ToBytes32(lastValidHash))
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if err := s.removeInvalidBlockAndState(ctx, invalidRoots); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"slot": blk.Block().Slot(),
|
||||||
|
"blockRoot": fmt.Sprintf("%#x", root),
|
||||||
|
"invalidCount": len(invalidRoots),
|
||||||
|
}).Warn("Pruned invalid blocks")
|
||||||
|
return false, ErrInvalidPayload
|
||||||
|
default:
|
||||||
|
return false, errors.WithMessage(ErrUndefinedExecutionEngineError, err.Error())
|
||||||
}
|
}
|
||||||
return true, s.validateMergeBlock(ctx, blk)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimisticCandidateBlock returns true if this block can be optimistically synced.
|
// optimisticCandidateBlock returns an error if this block can't be optimistically synced.
|
||||||
|
// It replaces boolean in spec code with `errNotOptimisticCandidate`.
|
||||||
//
|
//
|
||||||
// Spec pseudocode definition:
|
// Spec pseudocode definition:
|
||||||
// def is_optimistic_candidate_block(opt_store: OptimisticStore, current_slot: Slot, block: BeaconBlock) -> bool:
|
// def is_optimistic_candidate_block(opt_store: OptimisticStore, current_slot: Slot, block: BeaconBlock) -> bool:
|
||||||
@@ -185,24 +231,27 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion, postSta
|
|||||||
// return True
|
// return True
|
||||||
//
|
//
|
||||||
// return False
|
// return False
|
||||||
func (s *Service) optimisticCandidateBlock(ctx context.Context, blk block.BeaconBlock) (bool, error) {
|
func (s *Service) optimisticCandidateBlock(ctx context.Context, blk interfaces.BeaconBlock) error {
|
||||||
if blk.Slot()+params.BeaconConfig().SafeSlotsToImportOptimistically <= s.CurrentSlot() {
|
if blk.Slot()+params.BeaconConfig().SafeSlotsToImportOptimistically <= s.CurrentSlot() {
|
||||||
return true, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parent, err := s.cfg.BeaconDB.Block(ctx, bytesutil.ToBytes32(blk.ParentRoot()))
|
parent, err := s.cfg.BeaconDB.Block(ctx, bytesutil.ToBytes32(blk.ParentRoot()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
if parent == nil {
|
if parent == nil || parent.IsNil() {
|
||||||
return false, errNilParentInDB
|
return errNilParentInDB
|
||||||
}
|
}
|
||||||
|
|
||||||
parentIsExecutionBlock, err := blocks.IsExecutionBlock(parent.Block().Body())
|
parentIsExecutionBlock, err := blocks.IsExecutionBlock(parent.Block().Body())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
return parentIsExecutionBlock, nil
|
if parentIsExecutionBlock {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return errNotOptimisticCandidate
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPayloadAttributes returns the payload attributes for the given state and slot.
|
// getPayloadAttributes returns the payload attributes for the given state and slot.
|
||||||
@@ -6,10 +6,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||||
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||||
@@ -17,12 +17,12 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
v1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
v1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -57,11 +57,14 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 0, [32]byte{}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0))
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 0, [32]byte{}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 1, [32]byte{'a'}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0))
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
blk block.BeaconBlock
|
blk interfaces.BeaconBlock
|
||||||
|
headRoot [32]byte
|
||||||
finalizedRoot [32]byte
|
finalizedRoot [32]byte
|
||||||
|
justifiedRoot [32]byte
|
||||||
newForkchoiceErr error
|
newForkchoiceErr error
|
||||||
errString string
|
errString string
|
||||||
}{
|
}{
|
||||||
@@ -71,7 +74,7 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "phase0 block",
|
name: "phase0 block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}})
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return b
|
return b
|
||||||
@@ -79,7 +82,7 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "altair block",
|
name: "altair block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}})
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockAltair{Body: ðpb.BeaconBlockBodyAltair{}})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return b
|
return b
|
||||||
@@ -87,7 +90,7 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "not execution block",
|
name: "not execution block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
ExecutionPayload: &v1.ExecutionPayload{
|
ExecutionPayload: &v1.ExecutionPayload{
|
||||||
@@ -108,7 +111,7 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "happy case: finalized root is altair block",
|
name: "happy case: finalized root is altair block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
ExecutionPayload: &v1.ExecutionPayload{},
|
ExecutionPayload: &v1.ExecutionPayload{},
|
||||||
@@ -118,10 +121,11 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
return b
|
return b
|
||||||
}(),
|
}(),
|
||||||
finalizedRoot: altairBlkRoot,
|
finalizedRoot: altairBlkRoot,
|
||||||
|
justifiedRoot: altairBlkRoot,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "happy case: finalized root is bellatrix block",
|
name: "happy case: finalized root is bellatrix block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
ExecutionPayload: &v1.ExecutionPayload{},
|
ExecutionPayload: &v1.ExecutionPayload{},
|
||||||
@@ -131,10 +135,11 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
return b
|
return b
|
||||||
}(),
|
}(),
|
||||||
finalizedRoot: bellatrixBlkRoot,
|
finalizedRoot: bellatrixBlkRoot,
|
||||||
|
justifiedRoot: bellatrixBlkRoot,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forkchoice updated with optimistic block",
|
name: "forkchoice updated with optimistic block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
ExecutionPayload: &v1.ExecutionPayload{},
|
ExecutionPayload: &v1.ExecutionPayload{},
|
||||||
@@ -145,10 +150,11 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
newForkchoiceErr: powchain.ErrAcceptedSyncingPayloadStatus,
|
newForkchoiceErr: powchain.ErrAcceptedSyncingPayloadStatus,
|
||||||
finalizedRoot: bellatrixBlkRoot,
|
finalizedRoot: bellatrixBlkRoot,
|
||||||
|
justifiedRoot: bellatrixBlkRoot,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "forkchoice updated with invalid block",
|
name: "forkchoice updated with invalid block",
|
||||||
blk: func() block.BeaconBlock {
|
blk: func() interfaces.BeaconBlock {
|
||||||
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
b, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
ExecutionPayload: &v1.ExecutionPayload{},
|
ExecutionPayload: &v1.ExecutionPayload{},
|
||||||
@@ -159,7 +165,9 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
newForkchoiceErr: powchain.ErrInvalidPayloadStatus,
|
newForkchoiceErr: powchain.ErrInvalidPayloadStatus,
|
||||||
finalizedRoot: bellatrixBlkRoot,
|
finalizedRoot: bellatrixBlkRoot,
|
||||||
errString: "could not notify forkchoice update from execution engine: payload status is INVALID",
|
justifiedRoot: bellatrixBlkRoot,
|
||||||
|
headRoot: [32]byte{'a'},
|
||||||
|
errString: ErrInvalidPayload.Error(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +175,17 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
service.cfg.ExecutionEngineCaller = &mockPOW.EngineClient{ErrForkchoiceUpdated: tt.newForkchoiceErr}
|
service.cfg.ExecutionEngineCaller = &mockPOW.EngineClient{ErrForkchoiceUpdated: tt.newForkchoiceErr}
|
||||||
st, _ := util.DeterministicGenesisState(t, 1)
|
st, _ := util.DeterministicGenesisState(t, 1)
|
||||||
_, err := service.notifyForkchoiceUpdate(ctx, st, tt.blk, service.headRoot(), tt.finalizedRoot)
|
require.NoError(t, beaconDB.SaveState(ctx, st, tt.finalizedRoot))
|
||||||
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, tt.finalizedRoot))
|
||||||
|
fc := ðpb.Checkpoint{Epoch: 1, Root: tt.finalizedRoot[:]}
|
||||||
|
service.store.SetFinalizedCheckptAndPayloadHash(fc, [32]byte{'a'})
|
||||||
|
service.store.SetJustifiedCheckptAndPayloadHash(fc, [32]byte{'b'})
|
||||||
|
arg := ¬ifyForkchoiceUpdateArg{
|
||||||
|
headState: st,
|
||||||
|
headRoot: tt.headRoot,
|
||||||
|
headBlock: tt.blk,
|
||||||
|
}
|
||||||
|
_, err := service.notifyForkchoiceUpdate(ctx, arg)
|
||||||
if tt.errString != "" {
|
if tt.errString != "" {
|
||||||
require.ErrorContains(t, tt.errString, err)
|
require.ErrorContains(t, tt.errString, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -177,6 +195,147 @@ func Test_NotifyForkchoiceUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A <- B <- C <- D
|
||||||
|
// \
|
||||||
|
// ---------- E <- F
|
||||||
|
// \
|
||||||
|
// ------ G
|
||||||
|
// D is the current head, attestations for F and G come late, both are invalid.
|
||||||
|
// We switch recursively to F then G and finally to D.
|
||||||
|
//
|
||||||
|
// We test:
|
||||||
|
// 1. forkchoice removes blocks F and G from the forkchoice implementation
|
||||||
|
// 2. forkchoice removes the weights of these blocks
|
||||||
|
// 3. the blockchain package calls fcu to obtain heads G -> F -> D.
|
||||||
|
|
||||||
|
func Test_NotifyForkchoiceUpdateRecursive(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
|
||||||
|
// Prepare blocks
|
||||||
|
ba := util.NewBeaconBlockBellatrix()
|
||||||
|
ba.Block.Body.ExecutionPayload.BlockNumber = 1
|
||||||
|
wba, err := wrapper.WrappedSignedBeaconBlock(ba)
|
||||||
|
require.NoError(t, err)
|
||||||
|
bra, err := wba.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wba))
|
||||||
|
|
||||||
|
bb := util.NewBeaconBlockBellatrix()
|
||||||
|
bb.Block.Body.ExecutionPayload.BlockNumber = 2
|
||||||
|
wbb, err := wrapper.WrappedSignedBeaconBlock(bb)
|
||||||
|
require.NoError(t, err)
|
||||||
|
brb, err := wbb.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbb))
|
||||||
|
|
||||||
|
bc := util.NewBeaconBlockBellatrix()
|
||||||
|
bc.Block.Body.ExecutionPayload.BlockNumber = 3
|
||||||
|
wbc, err := wrapper.WrappedSignedBeaconBlock(bc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
brc, err := wbc.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbc))
|
||||||
|
|
||||||
|
bd := util.NewBeaconBlockBellatrix()
|
||||||
|
pd := [32]byte{'D'}
|
||||||
|
bd.Block.Body.ExecutionPayload.BlockHash = pd[:]
|
||||||
|
bd.Block.Body.ExecutionPayload.BlockNumber = 4
|
||||||
|
wbd, err := wrapper.WrappedSignedBeaconBlock(bd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
brd, err := wbd.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbd))
|
||||||
|
|
||||||
|
be := util.NewBeaconBlockBellatrix()
|
||||||
|
pe := [32]byte{'E'}
|
||||||
|
be.Block.Body.ExecutionPayload.BlockHash = pe[:]
|
||||||
|
be.Block.Body.ExecutionPayload.BlockNumber = 5
|
||||||
|
wbe, err := wrapper.WrappedSignedBeaconBlock(be)
|
||||||
|
require.NoError(t, err)
|
||||||
|
bre, err := wbe.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbe))
|
||||||
|
|
||||||
|
bf := util.NewBeaconBlockBellatrix()
|
||||||
|
pf := [32]byte{'F'}
|
||||||
|
bf.Block.Body.ExecutionPayload.BlockHash = pf[:]
|
||||||
|
bf.Block.Body.ExecutionPayload.BlockNumber = 6
|
||||||
|
bf.Block.ParentRoot = bre[:]
|
||||||
|
wbf, err := wrapper.WrappedSignedBeaconBlock(bf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
brf, err := wbf.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbf))
|
||||||
|
|
||||||
|
bg := util.NewBeaconBlockBellatrix()
|
||||||
|
bg.Block.Body.ExecutionPayload.BlockNumber = 7
|
||||||
|
pg := [32]byte{'G'}
|
||||||
|
bg.Block.Body.ExecutionPayload.BlockHash = pg[:]
|
||||||
|
bg.Block.ParentRoot = bre[:]
|
||||||
|
wbg, err := wrapper.WrappedSignedBeaconBlock(bg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
brg, err := wbg.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconDB.SaveBlock(ctx, wbg))
|
||||||
|
|
||||||
|
// Insert blocks into forkchoice
|
||||||
|
fcs := doublylinkedtree.New(0, 0)
|
||||||
|
opts := []Option{
|
||||||
|
WithDatabase(beaconDB),
|
||||||
|
WithStateGen(stategen.New(beaconDB)),
|
||||||
|
WithForkChoiceStore(fcs),
|
||||||
|
WithProposerIdsCache(cache.NewProposerPayloadIDsCache()),
|
||||||
|
}
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
service.justifiedBalances.balances = []uint64{50, 100, 200}
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 1, bra, [32]byte{}, [32]byte{'A'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 2, brb, bra, [32]byte{'B'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 3, brc, brb, [32]byte{'C'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 4, brd, brc, [32]byte{'D'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 5, bre, brb, [32]byte{'E'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 6, brf, bre, [32]byte{'F'}, 0, 0))
|
||||||
|
require.NoError(t, fcs.InsertOptimisticBlock(ctx, 7, brg, bre, [32]byte{'G'}, 0, 0))
|
||||||
|
|
||||||
|
// Insert Attestations to D, F and G so that they have higher weight than D
|
||||||
|
// Ensure G is head
|
||||||
|
fcs.ProcessAttestation(ctx, []uint64{0}, brd, 1)
|
||||||
|
fcs.ProcessAttestation(ctx, []uint64{1}, brf, 1)
|
||||||
|
fcs.ProcessAttestation(ctx, []uint64{2}, brg, 1)
|
||||||
|
headRoot, err := fcs.Head(ctx, 0, bra, []uint64{50, 100, 200}, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, brg, headRoot)
|
||||||
|
|
||||||
|
// Prepare Engine Mock to return invalid unless head is D, LVH = E
|
||||||
|
service.cfg.ExecutionEngineCaller = &mockPOW.EngineClient{ErrForkchoiceUpdated: powchain.ErrInvalidPayloadStatus, ForkChoiceUpdatedResp: pe[:], OverrideValidHash: [32]byte{'D'}}
|
||||||
|
st, _ := util.DeterministicGenesisState(t, 1)
|
||||||
|
|
||||||
|
require.NoError(t, beaconDB.SaveState(ctx, st, bra))
|
||||||
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, bra))
|
||||||
|
fc := ðpb.Checkpoint{Epoch: 0, Root: bra[:]}
|
||||||
|
service.store.SetFinalizedCheckptAndPayloadHash(fc, [32]byte{'a'})
|
||||||
|
service.store.SetJustifiedCheckptAndPayloadHash(fc, [32]byte{'b'})
|
||||||
|
a := ¬ifyForkchoiceUpdateArg{
|
||||||
|
headState: st,
|
||||||
|
headBlock: wbg.Block(),
|
||||||
|
headRoot: brg,
|
||||||
|
}
|
||||||
|
_, err = service.notifyForkchoiceUpdate(ctx, a)
|
||||||
|
require.ErrorIs(t, ErrInvalidPayload, err)
|
||||||
|
// Ensure Head is D
|
||||||
|
headRoot, err = fcs.Head(ctx, 0, bra, service.justifiedBalances.balances, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, brd, headRoot)
|
||||||
|
|
||||||
|
// Ensure F and G where removed but their parent E wasn't
|
||||||
|
require.Equal(t, false, fcs.HasNode(brf))
|
||||||
|
require.Equal(t, false, fcs.HasNode(brg))
|
||||||
|
require.Equal(t, true, fcs.HasNode(bre))
|
||||||
|
}
|
||||||
|
|
||||||
func Test_NotifyNewPayload(t *testing.T) {
|
func Test_NotifyNewPayload(t *testing.T) {
|
||||||
cfg := params.BeaconConfig()
|
cfg := params.BeaconConfig()
|
||||||
cfg.TerminalTotalDifficulty = "2"
|
cfg.TerminalTotalDifficulty = "2"
|
||||||
@@ -229,36 +388,31 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
preState state.BeaconState
|
|
||||||
postState state.BeaconState
|
postState state.BeaconState
|
||||||
isValidPayload bool
|
isValidPayload bool
|
||||||
blk block.SignedBeaconBlock
|
blk interfaces.SignedBeaconBlock
|
||||||
newPayloadErr error
|
newPayloadErr error
|
||||||
errString string
|
errString string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "phase 0 post state",
|
name: "phase 0 post state",
|
||||||
postState: phase0State,
|
postState: phase0State,
|
||||||
preState: phase0State,
|
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "altair post state",
|
name: "altair post state",
|
||||||
postState: altairState,
|
postState: altairState,
|
||||||
preState: altairState,
|
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nil beacon block",
|
name: "nil beacon block",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: bellatrixState,
|
|
||||||
errString: "signed beacon block can't be nil",
|
errString: "signed beacon block can't be nil",
|
||||||
isValidPayload: false,
|
isValidPayload: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "new payload with optimistic block",
|
name: "new payload with optimistic block",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: bellatrixState,
|
|
||||||
blk: bellatrixBlk,
|
blk: bellatrixBlk,
|
||||||
newPayloadErr: powchain.ErrAcceptedSyncingPayloadStatus,
|
newPayloadErr: powchain.ErrAcceptedSyncingPayloadStatus,
|
||||||
isValidPayload: false,
|
isValidPayload: false,
|
||||||
@@ -266,24 +420,21 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "new payload with invalid block",
|
name: "new payload with invalid block",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: bellatrixState,
|
|
||||||
blk: bellatrixBlk,
|
blk: bellatrixBlk,
|
||||||
newPayloadErr: powchain.ErrInvalidPayloadStatus,
|
newPayloadErr: powchain.ErrInvalidPayloadStatus,
|
||||||
errString: "could not validate an INVALID payload from execution engine",
|
errString: ErrInvalidPayload.Error(),
|
||||||
isValidPayload: false,
|
isValidPayload: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "altair pre state, altair block",
|
name: "altair pre state, altair block",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: altairState,
|
|
||||||
blk: altairBlk,
|
blk: altairBlk,
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "altair pre state, happy case",
|
name: "altair pre state, happy case",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: altairState,
|
blk: func() interfaces.SignedBeaconBlock {
|
||||||
blk: func() block.SignedBeaconBlock {
|
|
||||||
blk := ðpb.SignedBeaconBlockBellatrix{
|
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||||
Block: ðpb.BeaconBlockBellatrix{
|
Block: ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
@@ -299,19 +450,10 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "could not get merge block",
|
|
||||||
postState: bellatrixState,
|
|
||||||
preState: bellatrixState,
|
|
||||||
blk: bellatrixBlk,
|
|
||||||
errString: "could not get merge block parent hash and total difficulty",
|
|
||||||
isValidPayload: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "not at merge transition",
|
name: "not at merge transition",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: bellatrixState,
|
blk: func() interfaces.SignedBeaconBlock {
|
||||||
blk: func() block.SignedBeaconBlock {
|
|
||||||
blk := ðpb.SignedBeaconBlockBellatrix{
|
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||||
Block: ðpb.BeaconBlockBellatrix{
|
Block: ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
@@ -334,19 +476,10 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "could not get merge block",
|
|
||||||
postState: bellatrixState,
|
|
||||||
preState: bellatrixState,
|
|
||||||
blk: bellatrixBlk,
|
|
||||||
errString: "could not get merge block parent hash and total difficulty",
|
|
||||||
isValidPayload: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "happy case",
|
name: "happy case",
|
||||||
postState: bellatrixState,
|
postState: bellatrixState,
|
||||||
preState: bellatrixState,
|
blk: func() interfaces.SignedBeaconBlock {
|
||||||
blk: func() block.SignedBeaconBlock {
|
|
||||||
blk := ðpb.SignedBeaconBlockBellatrix{
|
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||||
Block: ðpb.BeaconBlockBellatrix{
|
Block: ðpb.BeaconBlockBellatrix{
|
||||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
@@ -362,6 +495,26 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
isValidPayload: true,
|
isValidPayload: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "undefined error from ee",
|
||||||
|
postState: bellatrixState,
|
||||||
|
blk: func() interfaces.SignedBeaconBlock {
|
||||||
|
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||||
|
Block: ðpb.BeaconBlockBellatrix{
|
||||||
|
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||||
|
ExecutionPayload: &v1.ExecutionPayload{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
b, err := wrapper.WrappedSignedBeaconBlock(blk)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return b
|
||||||
|
}(),
|
||||||
|
newPayloadErr: ErrUndefinedExecutionEngineError,
|
||||||
|
errString: ErrUndefinedExecutionEngineError.Error(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -375,16 +528,11 @@ func Test_NotifyNewPayload(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
}
|
}
|
||||||
service.cfg.ExecutionEngineCaller = e
|
service.cfg.ExecutionEngineCaller = e
|
||||||
var payload *ethpb.ExecutionPayloadHeader
|
|
||||||
if tt.preState.Version() == version.Bellatrix {
|
|
||||||
payload, err = tt.preState.LatestExecutionPayloadHeader()
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
root := [32]byte{'a'}
|
root := [32]byte{'a'}
|
||||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertOptimisticBlock(ctx, 0, root, root, params.BeaconConfig().ZeroHash, 0, 0))
|
require.NoError(t, service.cfg.ForkChoiceStore.InsertOptimisticBlock(ctx, 0, root, root, params.BeaconConfig().ZeroHash, 0, 0))
|
||||||
postVersion, postHeader, err := getStateVersionAndPayload(tt.postState)
|
postVersion, postHeader, err := getStateVersionAndPayload(tt.postState)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
isValidPayload, err := service.notifyNewPayload(ctx, tt.preState.Version(), postVersion, payload, postHeader, tt.blk)
|
isValidPayload, err := service.notifyNewPayload(ctx, postVersion, postHeader, tt.blk)
|
||||||
if tt.errString != "" {
|
if tt.errString != "" {
|
||||||
require.ErrorContains(t, tt.errString, err)
|
require.ErrorContains(t, tt.errString, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -431,11 +579,9 @@ func Test_NotifyNewPayload_SetOptimisticToValid(t *testing.T) {
|
|||||||
TotalDifficulty: "0x1",
|
TotalDifficulty: "0x1",
|
||||||
}
|
}
|
||||||
service.cfg.ExecutionEngineCaller = e
|
service.cfg.ExecutionEngineCaller = e
|
||||||
payload, err := bellatrixState.LatestExecutionPayloadHeader()
|
|
||||||
require.NoError(t, err)
|
|
||||||
postVersion, postHeader, err := getStateVersionAndPayload(bellatrixState)
|
postVersion, postHeader, err := getStateVersionAndPayload(bellatrixState)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
validated, err := service.notifyNewPayload(ctx, bellatrixState.Version(), postVersion, payload, postHeader, bellatrixBlk)
|
validated, err := service.notifyNewPayload(ctx, postVersion, postHeader, bellatrixBlk)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, true, validated)
|
require.Equal(t, true, validated)
|
||||||
}
|
}
|
||||||
@@ -467,13 +613,13 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
blk block.BeaconBlock
|
blk interfaces.BeaconBlock
|
||||||
justified block.SignedBeaconBlock
|
justified interfaces.SignedBeaconBlock
|
||||||
want bool
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "deep block",
|
name: "deep block",
|
||||||
blk: func(tt *testing.T) block.BeaconBlock {
|
blk: func(tt *testing.T) interfaces.BeaconBlock {
|
||||||
blk := util.NewBeaconBlockBellatrix()
|
blk := util.NewBeaconBlockBellatrix()
|
||||||
blk.Block.Slot = 1
|
blk.Block.Slot = 1
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -481,7 +627,7 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
justified: func(tt *testing.T) block.SignedBeaconBlock {
|
justified: func(tt *testing.T) interfaces.SignedBeaconBlock {
|
||||||
blk := util.NewBeaconBlockBellatrix()
|
blk := util.NewBeaconBlockBellatrix()
|
||||||
blk.Block.Slot = 32
|
blk.Block.Slot = 32
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -489,11 +635,11 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
want: true,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "shallow block, Altair justified chkpt",
|
name: "shallow block, Altair justified chkpt",
|
||||||
blk: func(tt *testing.T) block.BeaconBlock {
|
blk: func(tt *testing.T) interfaces.BeaconBlock {
|
||||||
blk := util.NewBeaconBlockAltair()
|
blk := util.NewBeaconBlockAltair()
|
||||||
blk.Block.Slot = 200
|
blk.Block.Slot = 200
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -501,7 +647,7 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
justified: func(tt *testing.T) block.SignedBeaconBlock {
|
justified: func(tt *testing.T) interfaces.SignedBeaconBlock {
|
||||||
blk := util.NewBeaconBlockAltair()
|
blk := util.NewBeaconBlockAltair()
|
||||||
blk.Block.Slot = 32
|
blk.Block.Slot = 32
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -509,11 +655,11 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
want: false,
|
err: errNotOptimisticCandidate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "shallow block, Bellatrix justified chkpt without execution",
|
name: "shallow block, Bellatrix justified chkpt without execution",
|
||||||
blk: func(tt *testing.T) block.BeaconBlock {
|
blk: func(tt *testing.T) interfaces.BeaconBlock {
|
||||||
blk := util.NewBeaconBlockBellatrix()
|
blk := util.NewBeaconBlockBellatrix()
|
||||||
blk.Block.Slot = 200
|
blk.Block.Slot = 200
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -521,7 +667,7 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
justified: func(tt *testing.T) block.SignedBeaconBlock {
|
justified: func(tt *testing.T) interfaces.SignedBeaconBlock {
|
||||||
blk := util.NewBeaconBlockBellatrix()
|
blk := util.NewBeaconBlockBellatrix()
|
||||||
blk.Block.Slot = 32
|
blk.Block.Slot = 32
|
||||||
blk.Block.ParentRoot = parentRoot[:]
|
blk.Block.ParentRoot = parentRoot[:]
|
||||||
@@ -529,23 +675,22 @@ func Test_IsOptimisticCandidateBlock(t *testing.T) {
|
|||||||
require.NoError(tt, err)
|
require.NoError(tt, err)
|
||||||
return wr
|
return wr
|
||||||
}(t),
|
}(t),
|
||||||
want: false,
|
err: errNotOptimisticCandidate,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
jRoot, err := tt.justified.Block().HashTreeRoot()
|
jRoot, err := tt.justified.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, tt.justified))
|
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, tt.justified))
|
||||||
service.store.SetJustifiedCheckpt(
|
service.store.SetJustifiedCheckptAndPayloadHash(
|
||||||
ðpb.Checkpoint{
|
ðpb.Checkpoint{
|
||||||
Root: jRoot[:],
|
Root: jRoot[:],
|
||||||
Epoch: slots.ToEpoch(tt.justified.Block().Slot()),
|
Epoch: slots.ToEpoch(tt.justified.Block().Slot()),
|
||||||
})
|
}, [32]byte{'a'})
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrappedParentBlock))
|
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrappedParentBlock))
|
||||||
|
|
||||||
candidate, err := service.optimisticCandidateBlock(ctx, tt.blk)
|
err = service.optimisticCandidateBlock(ctx, tt.blk)
|
||||||
require.NoError(t, err)
|
require.Equal(t, tt.err, err)
|
||||||
require.Equal(t, tt.want, candidate, tt.name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,9 +738,8 @@ func Test_IsOptimisticShallowExecutionParent(t *testing.T) {
|
|||||||
wrappedChild, err := wrapper.WrappedSignedBeaconBlock(childBlock)
|
wrappedChild, err := wrapper.WrappedSignedBeaconBlock(childBlock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrappedChild))
|
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wrappedChild))
|
||||||
candidate, err := service.optimisticCandidateBlock(ctx, wrappedChild.Block())
|
err = service.optimisticCandidateBlock(ctx, wrappedChild.Block())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, true, candidate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_GetPayloadAttribute(t *testing.T) {
|
func Test_GetPayloadAttribute(t *testing.T) {
|
||||||
@@ -792,3 +936,42 @@ func TestService_removeInvalidBlockAndState(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, false, has)
|
require.Equal(t, false, has)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestService_getPayloadHash(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
opts := []Option{
|
||||||
|
WithDatabase(beaconDB),
|
||||||
|
WithStateGen(stategen.New(beaconDB)),
|
||||||
|
WithForkChoiceStore(protoarray.New(0, 0, [32]byte{})),
|
||||||
|
}
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = service.getPayloadHash(ctx, []byte{})
|
||||||
|
require.ErrorIs(t, errBlockNotFoundInCacheOrDB, err)
|
||||||
|
|
||||||
|
b := util.NewBeaconBlock()
|
||||||
|
r, err := b.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
service.saveInitSyncBlock(r, wsb)
|
||||||
|
|
||||||
|
h, err := service.getPayloadHash(ctx, r[:])
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.DeepEqual(t, params.BeaconConfig().ZeroHash, h)
|
||||||
|
|
||||||
|
bb := util.NewBeaconBlockBellatrix()
|
||||||
|
h = [32]byte{'a'}
|
||||||
|
bb.Block.Body.ExecutionPayload.BlockHash = h[:]
|
||||||
|
r, err = b.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb, err = wrapper.WrappedSignedBeaconBlock(bb)
|
||||||
|
require.NoError(t, err)
|
||||||
|
service.saveInitSyncBlock(r, wsb)
|
||||||
|
|
||||||
|
h, err = service.getPayloadHash(ctx, r[:])
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.DeepEqual(t, [32]byte{'a'}, h)
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
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/helpers"
|
||||||
@@ -16,9 +15,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@@ -53,10 +53,10 @@ func (s *Service) UpdateAndSaveHeadWithBalances(ctx context.Context) error {
|
|||||||
|
|
||||||
// This defines the current chain service's view of head.
|
// This defines the current chain service's view of head.
|
||||||
type head struct {
|
type head struct {
|
||||||
slot types.Slot // current head slot.
|
slot types.Slot // current head slot.
|
||||||
root [32]byte // current head root.
|
root [32]byte // current head root.
|
||||||
block block.SignedBeaconBlock // current head block.
|
block interfaces.SignedBeaconBlock // current head block.
|
||||||
state state.BeaconState // current head state.
|
state state.BeaconState // current head state.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determined the head from the fork choice service and saves its new data
|
// Determined the head from the fork choice service and saves its new data
|
||||||
@@ -105,7 +105,7 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) ([32]byte,
|
|||||||
|
|
||||||
// This saves head info to the local service cache, it also saves the
|
// This saves head info to the local service cache, it also saves the
|
||||||
// new head root to the DB.
|
// new head root to the DB.
|
||||||
func (s *Service) saveHead(ctx context.Context, headRoot [32]byte, headBlock block.SignedBeaconBlock, headState state.BeaconState) error {
|
func (s *Service) saveHead(ctx context.Context, headRoot [32]byte, headBlock interfaces.SignedBeaconBlock, headState state.BeaconState) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.saveHead")
|
ctx, span := trace.StartSpan(ctx, "blockChain.saveHead")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte, headBlock blo
|
|||||||
// This gets called to update canonical root mapping. It does not save head block
|
// 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
|
// 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.
|
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
|
||||||
func (s *Service) saveHeadNoDB(ctx context.Context, b block.SignedBeaconBlock, r [32]byte, hs state.BeaconState) error {
|
func (s *Service) saveHeadNoDB(ctx context.Context, b interfaces.SignedBeaconBlock, r [32]byte, hs state.BeaconState) error {
|
||||||
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b block.SignedBeaconBlock, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This sets head view object which is used to track the head slot, root, block and state.
|
// 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 block.SignedBeaconBlock, state state.BeaconState) {
|
func (s *Service) setHead(root [32]byte, block interfaces.SignedBeaconBlock, state state.BeaconState) {
|
||||||
s.headLock.Lock()
|
s.headLock.Lock()
|
||||||
defer s.headLock.Unlock()
|
defer s.headLock.Unlock()
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ func (s *Service) setHead(root [32]byte, block block.SignedBeaconBlock, state st
|
|||||||
// This sets head view object which is used to track the head slot, root, block and state. The method
|
// 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
|
// assumes that state being passed into the method will not be modified by any other alternate
|
||||||
// caller which holds the state's reference.
|
// caller which holds the state's reference.
|
||||||
func (s *Service) setHeadInitialSync(root [32]byte, block block.SignedBeaconBlock, state state.BeaconState) {
|
func (s *Service) setHeadInitialSync(root [32]byte, block interfaces.SignedBeaconBlock, state state.BeaconState) {
|
||||||
s.headLock.Lock()
|
s.headLock.Lock()
|
||||||
defer s.headLock.Unlock()
|
defer s.headLock.Unlock()
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ func (s *Service) headRoot() [32]byte {
|
|||||||
// This returns the head block.
|
// This returns the head block.
|
||||||
// It does a full copy on head block for immutability.
|
// It does a full copy on head block for immutability.
|
||||||
// This is a lock free version.
|
// This is a lock free version.
|
||||||
func (s *Service) headBlock() block.SignedBeaconBlock {
|
func (s *Service) headBlock() interfaces.SignedBeaconBlock {
|
||||||
return s.head.block.Copy()
|
return s.head.block.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,10 +355,6 @@ func (s *Service) notifyNewHeadEvent(
|
|||||||
// attestation pool. It also filters out the attestations that is one epoch older as a
|
// attestation pool. It also filters out the attestations that is one epoch older as a
|
||||||
// defense so invalid attestations don't flow into the attestation pool.
|
// defense so invalid attestations don't flow into the attestation pool.
|
||||||
func (s *Service) saveOrphanedAtts(ctx context.Context, orphanedRoot [32]byte) error {
|
func (s *Service) saveOrphanedAtts(ctx context.Context, orphanedRoot [32]byte) error {
|
||||||
if !features.Get().CorrectlyInsertOrphanedAtts {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
orphanedBlk, err := s.cfg.BeaconDB.Block(ctx, orphanedRoot)
|
orphanedBlk, err := s.cfg.BeaconDB.Block(ctx, orphanedRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/async"
|
"github.com/prysmaticlabs/prysm/async"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
|
|||||||
@@ -6,16 +6,15 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -155,8 +154,8 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
|
|||||||
r, err := b.Block.HashTreeRoot()
|
r, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r[:]}, [32]byte{'a'})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{}, [32]byte{'b'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{})
|
||||||
headRoot, err := service.updateHead(context.Background(), []uint64{})
|
headRoot, err := service.updateHead(context.Background(), []uint64{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -231,11 +230,6 @@ func Test_notifyNewHeadEvent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSaveOrphanedAtts(t *testing.T) {
|
func TestSaveOrphanedAtts(t *testing.T) {
|
||||||
resetCfg := features.InitWithReset(&features.Flags{
|
|
||||||
CorrectlyInsertOrphanedAtts: true,
|
|
||||||
})
|
|
||||||
defer resetCfg()
|
|
||||||
|
|
||||||
genesis, keys := util.DeterministicGenesisState(t, 64)
|
genesis, keys := util.DeterministicGenesisState(t, 64)
|
||||||
b, err := util.GenerateFullBlock(genesis, keys, util.DefaultBlockGenConfig(), 1)
|
b, err := util.GenerateFullBlock(genesis, keys, util.DefaultBlockGenConfig(), 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -259,11 +253,6 @@ func TestSaveOrphanedAtts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSaveOrphanedAtts_CanFilter(t *testing.T) {
|
func TestSaveOrphanedAtts_CanFilter(t *testing.T) {
|
||||||
resetCfg := features.InitWithReset(&features.Flags{
|
|
||||||
CorrectlyInsertOrphanedAtts: true,
|
|
||||||
})
|
|
||||||
defer resetCfg()
|
|
||||||
|
|
||||||
genesis, keys := util.DeterministicGenesisState(t, 64)
|
genesis, keys := util.DeterministicGenesisState(t, 64)
|
||||||
b, err := util.GenerateFullBlock(genesis, keys, util.DefaultBlockGenConfig(), 1)
|
b, err := util.GenerateFullBlock(genesis, keys, util.DefaultBlockGenConfig(), 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -309,8 +298,8 @@ func TestUpdateHead_noSavedChanges(t *testing.T) {
|
|||||||
Root: bellatrixBlkRoot[:],
|
Root: bellatrixBlkRoot[:],
|
||||||
Epoch: 1,
|
Epoch: 1,
|
||||||
}
|
}
|
||||||
service.store.SetFinalizedCheckpt(fcp)
|
service.store.SetFinalizedCheckptAndPayloadHash(fcp, [32]byte{'a'})
|
||||||
service.store.SetJustifiedCheckpt(fcp)
|
service.store.SetJustifiedCheckptAndPayloadHash(fcp, [32]byte{'b'})
|
||||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, bellatrixBlkRoot))
|
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, bellatrixBlkRoot))
|
||||||
|
|
||||||
bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2)
|
bellatrixState, _ := util.DeterministicGenesisStateBellatrix(t, 2)
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
package blockchain
|
package blockchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var errBlockNotFoundInCacheOrDB = errors.New("block not found in cache or db")
|
||||||
|
|
||||||
// This saves a beacon block to the initial sync blocks cache.
|
// This saves a beacon block to the initial sync blocks cache.
|
||||||
func (s *Service) saveInitSyncBlock(r [32]byte, b block.SignedBeaconBlock) {
|
func (s *Service) saveInitSyncBlock(r [32]byte, b interfaces.SignedBeaconBlock) {
|
||||||
s.initSyncBlocksLock.Lock()
|
s.initSyncBlocksLock.Lock()
|
||||||
defer s.initSyncBlocksLock.Unlock()
|
defer s.initSyncBlocksLock.Unlock()
|
||||||
s.initSyncBlocks[r] = b
|
s.initSyncBlocks[r] = b
|
||||||
@@ -20,22 +26,42 @@ func (s *Service) hasInitSyncBlock(r [32]byte) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// This retrieves a beacon block from the initial sync blocks cache using the root of
|
// Returns true if a block for root `r` exists in the initial sync blocks cache or the DB.
|
||||||
// the block.
|
func (s *Service) hasBlockInInitSyncOrDB(ctx context.Context, r [32]byte) bool {
|
||||||
func (s *Service) getInitSyncBlock(r [32]byte) block.SignedBeaconBlock {
|
if s.hasInitSyncBlock(r) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return s.cfg.BeaconDB.HasBlock(ctx, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns block for a given root `r` from either the initial sync blocks cache or the DB.
|
||||||
|
// Error is returned if the block is not found in either cache or DB.
|
||||||
|
func (s *Service) getBlock(ctx context.Context, r [32]byte) (interfaces.SignedBeaconBlock, error) {
|
||||||
s.initSyncBlocksLock.RLock()
|
s.initSyncBlocksLock.RLock()
|
||||||
defer s.initSyncBlocksLock.RUnlock()
|
|
||||||
b := s.initSyncBlocks[r]
|
// Check cache first because it's faster.
|
||||||
return b
|
b, ok := s.initSyncBlocks[r]
|
||||||
|
s.initSyncBlocksLock.RUnlock()
|
||||||
|
var err error
|
||||||
|
if !ok {
|
||||||
|
b, err = s.cfg.BeaconDB.Block(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not retrieve block from db")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
|
return nil, errBlockNotFoundInCacheOrDB
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This retrieves all the beacon blocks from the initial sync blocks cache, the returned
|
// This retrieves all the beacon blocks from the initial sync blocks cache, the returned
|
||||||
// blocks are unordered.
|
// blocks are unordered.
|
||||||
func (s *Service) getInitSyncBlocks() []block.SignedBeaconBlock {
|
func (s *Service) getInitSyncBlocks() []interfaces.SignedBeaconBlock {
|
||||||
s.initSyncBlocksLock.RLock()
|
s.initSyncBlocksLock.RLock()
|
||||||
defer s.initSyncBlocksLock.RUnlock()
|
defer s.initSyncBlocksLock.RUnlock()
|
||||||
|
|
||||||
blks := make([]block.SignedBeaconBlock, 0, len(s.initSyncBlocks))
|
blks := make([]interfaces.SignedBeaconBlock, 0, len(s.initSyncBlocks))
|
||||||
for _, b := range s.initSyncBlocks {
|
for _, b := range s.initSyncBlocks {
|
||||||
blks = append(blks, b)
|
blks = append(blks, b)
|
||||||
}
|
}
|
||||||
@@ -46,5 +72,5 @@ func (s *Service) getInitSyncBlocks() []block.SignedBeaconBlock {
|
|||||||
func (s *Service) clearInitSyncBlocks() {
|
func (s *Service) clearInitSyncBlocks() {
|
||||||
s.initSyncBlocksLock.Lock()
|
s.initSyncBlocksLock.Lock()
|
||||||
defer s.initSyncBlocksLock.Unlock()
|
defer s.initSyncBlocksLock.Unlock()
|
||||||
s.initSyncBlocks = make(map[[32]byte]block.SignedBeaconBlock)
|
s.initSyncBlocks = make(map[[32]byte]interfaces.SignedBeaconBlock)
|
||||||
}
|
}
|
||||||
|
|||||||
72
beacon-chain/blockchain/init_sync_process_block_test.go
Normal file
72
beacon-chain/blockchain/init_sync_process_block_test.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package blockchain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestService_getBlock(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
s := setupBeaconChain(t, beaconDB)
|
||||||
|
b1 := util.NewBeaconBlock()
|
||||||
|
r1, err := b1.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b2 := util.NewBeaconBlock()
|
||||||
|
b2.Block.Slot = 100
|
||||||
|
r2, err := b2.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// block not found
|
||||||
|
_, err = s.getBlock(ctx, [32]byte{})
|
||||||
|
require.ErrorIs(t, err, errBlockNotFoundInCacheOrDB)
|
||||||
|
|
||||||
|
// block in cache
|
||||||
|
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
s.saveInitSyncBlock(r1, b)
|
||||||
|
got, err := s.getBlock(ctx, r1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.DeepEqual(t, b, got)
|
||||||
|
|
||||||
|
// block in db
|
||||||
|
b, err = wrapper.WrappedSignedBeaconBlock(b2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, s.cfg.BeaconDB.SaveBlock(ctx, b))
|
||||||
|
got, err = s.getBlock(ctx, r2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.DeepEqual(t, b, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestService_hasBlockInInitSyncOrDB(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
s := setupBeaconChain(t, beaconDB)
|
||||||
|
b1 := util.NewBeaconBlock()
|
||||||
|
r1, err := b1.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
b2 := util.NewBeaconBlock()
|
||||||
|
b2.Block.Slot = 100
|
||||||
|
r2, err := b2.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// block not found
|
||||||
|
require.Equal(t, false, s.hasBlockInInitSyncOrDB(ctx, [32]byte{}))
|
||||||
|
|
||||||
|
// block in cache
|
||||||
|
b, err := wrapper.WrappedSignedBeaconBlock(b1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
s.saveInitSyncBlock(r1, b)
|
||||||
|
require.Equal(t, true, s.hasBlockInInitSyncOrDB(ctx, r1))
|
||||||
|
|
||||||
|
// block in db
|
||||||
|
b, err = wrapper.WrappedSignedBeaconBlock(b2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, s.cfg.BeaconDB.SaveBlock(ctx, b))
|
||||||
|
require.Equal(t, true, s.hasBlockInInitSyncOrDB(ctx, r2))
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
prysmTime "github.com/prysmaticlabs/prysm/time"
|
prysmTime "github.com/prysmaticlabs/prysm/time"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
var log = logrus.WithField("prefix", "blockchain")
|
var log = logrus.WithField("prefix", "blockchain")
|
||||||
|
|
||||||
// logs state transition related data every slot.
|
// logs state transition related data every slot.
|
||||||
func logStateTransitionData(b block.BeaconBlock) error {
|
func logStateTransitionData(b interfaces.BeaconBlock) error {
|
||||||
log := log.WithField("slot", b.Slot())
|
log := log.WithField("slot", b.Slot())
|
||||||
if len(b.Body().Attestations()) > 0 {
|
if len(b.Body().Attestations()) > 0 {
|
||||||
log = log.WithField("attestations", len(b.Body().Attestations()))
|
log = log.WithField("attestations", len(b.Body().Attestations()))
|
||||||
@@ -54,7 +54,7 @@ func logStateTransitionData(b block.BeaconBlock) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func logBlockSyncStatus(block block.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
|
func logBlockSyncStatus(block interfaces.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
|
||||||
startTime, err := slots.ToTime(genesisTime, block.Slot())
|
startTime, err := slots.ToTime(genesisTime, block.Slot())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package blockchain
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
)
|
)
|
||||||
@@ -25,57 +25,85 @@ func Test_logStateTransitionData(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
b block.BeaconBlock
|
b func() interfaces.BeaconBlock
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{name: "empty block body",
|
{name: "empty block body",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}),
|
b: func() interfaces.BeaconBlock {
|
||||||
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" prefix=blockchain slot=0",
|
want: "\"Finished applying state transition\" prefix=blockchain slot=0",
|
||||||
},
|
},
|
||||||
{name: "has attestation",
|
{name: "has attestation",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{{}}}}),
|
b: func() interfaces.BeaconBlock {
|
||||||
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" attestations=1 prefix=blockchain slot=0",
|
want: "\"Finished applying state transition\" attestations=1 prefix=blockchain slot=0",
|
||||||
},
|
},
|
||||||
{name: "has deposit",
|
{name: "has deposit",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(
|
b: func() interfaces.BeaconBlock {
|
||||||
ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
wb, err := wrapper.WrappedBeaconBlock(
|
||||||
Attestations: []*ethpb.Attestation{{}},
|
ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
||||||
Deposits: []*ethpb.Deposit{{}}}}),
|
Attestations: []*ethpb.Attestation{{}},
|
||||||
|
Deposits: []*ethpb.Deposit{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" attestations=1 deposits=1 prefix=blockchain slot=0",
|
want: "\"Finished applying state transition\" attestations=1 deposits=1 prefix=blockchain slot=0",
|
||||||
},
|
},
|
||||||
{name: "has attester slashing",
|
{name: "has attester slashing",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
b: func() interfaces.BeaconBlock {
|
||||||
AttesterSlashings: []*ethpb.AttesterSlashing{{}}}}),
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
||||||
|
AttesterSlashings: []*ethpb.AttesterSlashing{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" attesterSlashings=1 prefix=blockchain slot=0",
|
want: "\"Finished applying state transition\" attesterSlashings=1 prefix=blockchain slot=0",
|
||||||
},
|
},
|
||||||
{name: "has proposer slashing",
|
{name: "has proposer slashing",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
b: func() interfaces.BeaconBlock {
|
||||||
ProposerSlashings: []*ethpb.ProposerSlashing{{}}}}),
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
||||||
|
ProposerSlashings: []*ethpb.ProposerSlashing{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" prefix=blockchain proposerSlashings=1 slot=0",
|
want: "\"Finished applying state transition\" prefix=blockchain proposerSlashings=1 slot=0",
|
||||||
},
|
},
|
||||||
{name: "has exit",
|
{name: "has exit",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
b: func() interfaces.BeaconBlock {
|
||||||
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}}),
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
||||||
|
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" prefix=blockchain slot=0 voluntaryExits=1",
|
want: "\"Finished applying state transition\" prefix=blockchain slot=0 voluntaryExits=1",
|
||||||
},
|
},
|
||||||
{name: "has everything",
|
{name: "has everything",
|
||||||
b: wrapper.WrappedPhase0BeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
b: func() interfaces.BeaconBlock {
|
||||||
Attestations: []*ethpb.Attestation{{}},
|
wb, err := wrapper.WrappedBeaconBlock(ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{
|
||||||
Deposits: []*ethpb.Deposit{{}},
|
Attestations: []*ethpb.Attestation{{}},
|
||||||
AttesterSlashings: []*ethpb.AttesterSlashing{{}},
|
Deposits: []*ethpb.Deposit{{}},
|
||||||
ProposerSlashings: []*ethpb.ProposerSlashing{{}},
|
AttesterSlashings: []*ethpb.AttesterSlashing{{}},
|
||||||
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}}),
|
ProposerSlashings: []*ethpb.ProposerSlashing{{}},
|
||||||
|
VoluntaryExits: []*ethpb.SignedVoluntaryExit{{}}}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
return wb
|
||||||
|
},
|
||||||
want: "\"Finished applying state transition\" attestations=1 attesterSlashings=1 deposits=1 prefix=blockchain proposerSlashings=1 slot=0 voluntaryExits=1",
|
want: "\"Finished applying state transition\" attestations=1 attesterSlashings=1 deposits=1 prefix=blockchain proposerSlashings=1 slot=0 voluntaryExits=1",
|
||||||
},
|
},
|
||||||
{name: "has payload",
|
{name: "has payload",
|
||||||
b: wrappedPayloadBlk,
|
b: func() interfaces.BeaconBlock { return wrappedPayloadBlk },
|
||||||
want: "\"Finished applying state transition\" payloadHash=0x010203 prefix=blockchain slot=0 syncBitsCount=0 txCount=2",
|
want: "\"Finished applying state transition\" payloadHash=0x010203 prefix=blockchain slot=0 syncBitsCount=0 txCount=2",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
hook := logTest.NewGlobal()
|
hook := logTest.NewGlobal()
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
require.NoError(t, logStateTransitionData(tt.b))
|
require.NoError(t, logStateTransitionData(tt.b()))
|
||||||
require.LogsContain(t, hook, tt.want)
|
require.LogsContain(t, hook, tt.want)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -138,6 +138,26 @@ var (
|
|||||||
Name: "state_balance_cache_miss",
|
Name: "state_balance_cache_miss",
|
||||||
Help: "Count the number of state balance cache hits.",
|
Help: "Count the number of state balance cache hits.",
|
||||||
})
|
})
|
||||||
|
newPayloadValidNodeCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "new_payload_valid_node_count",
|
||||||
|
Help: "Count the number of valid nodes after newPayload EE call",
|
||||||
|
})
|
||||||
|
newPayloadOptimisticNodeCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "new_payload_optimistic_node_count",
|
||||||
|
Help: "Count the number of optimistic nodes after newPayload EE call",
|
||||||
|
})
|
||||||
|
newPayloadInvalidNodeCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "new_payload_invalid_node_count",
|
||||||
|
Help: "Count the number of invalid nodes after newPayload EE call",
|
||||||
|
})
|
||||||
|
forkchoiceUpdatedValidNodeCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "forkchoice_updated_valid_node_count",
|
||||||
|
Help: "Count the number of valid nodes after forkchoiceUpdated EE call",
|
||||||
|
})
|
||||||
|
forkchoiceUpdatedOptimisticNodeCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "forkchoice_updated_optimistic_node_count",
|
||||||
|
Help: "Count the number of optimistic nodes after forkchoiceUpdated EE call",
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// reportSlotMetrics reports slot related metrics.
|
// reportSlotMetrics reports slot related metrics.
|
||||||
@@ -278,7 +298,7 @@ func reportEpochMetrics(ctx context.Context, postState, headState state.BeaconSt
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func reportAttestationInclusion(blk block.BeaconBlock) {
|
func reportAttestationInclusion(blk interfaces.BeaconBlock) {
|
||||||
for _, att := range blk.Body().Attestations() {
|
for _, att := range blk.Body().Attestations() {
|
||||||
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
|
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,7 +64,11 @@ func (s *Service) NewSlot(ctx context.Context, slot types.Slot) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if bytes.Equal(r, f.Root) {
|
if bytes.Equal(r, f.Root) {
|
||||||
s.store.SetJustifiedCheckpt(bj)
|
h, err := s.getPayloadHash(ctx, bj.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetJustifiedCheckptAndPayloadHash(bj, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -37,7 +37,7 @@ import (
|
|||||||
// assert pow_parent is not None
|
// assert pow_parent is not None
|
||||||
// # Check if `pow_block` is a valid terminal PoW block
|
// # Check if `pow_block` is a valid terminal PoW block
|
||||||
// assert is_valid_terminal_pow_block(pow_block, pow_parent)
|
// assert is_valid_terminal_pow_block(pow_block, pow_parent)
|
||||||
func (s *Service) validateMergeBlock(ctx context.Context, b block.SignedBeaconBlock) error {
|
func (s *Service) validateMergeBlock(ctx context.Context, b interfaces.SignedBeaconBlock) error {
|
||||||
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/async"
|
"github.com/prysmaticlabs/prysm/async"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
@@ -76,15 +76,10 @@ func verifyAttTargetEpoch(_ context.Context, genesisTime, nowTime uint64, c *eth
|
|||||||
// verifyBeaconBlock verifies beacon head block is known and not from the future.
|
// verifyBeaconBlock verifies beacon head block is known and not from the future.
|
||||||
func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.AttestationData) error {
|
func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.AttestationData) error {
|
||||||
r := bytesutil.ToBytes32(data.BeaconBlockRoot)
|
r := bytesutil.ToBytes32(data.BeaconBlockRoot)
|
||||||
b, err := s.cfg.BeaconDB.Block(ctx, r)
|
b, err := s.getBlock(ctx, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If the block does not exist in db, check again if block exists in initial sync block cache.
|
|
||||||
// This could happen as the node first syncs to head.
|
|
||||||
if (b == nil || b.IsNil()) && s.hasInitSyncBlock(r) {
|
|
||||||
b = s.getInitSyncBlock(r)
|
|
||||||
}
|
|
||||||
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
@@ -13,9 +12,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -324,9 +324,9 @@ func TestStore_SaveCheckpointState(t *testing.T) {
|
|||||||
r := [32]byte{'g'}
|
r := [32]byte{'g'}
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, r))
|
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, r))
|
||||||
|
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r[:]}, [32]byte{'a'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r[:]}, [32]byte{'b'})
|
||||||
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
||||||
|
|
||||||
r = bytesutil.ToBytes32([]byte{'A'})
|
r = bytesutil.ToBytes32([]byte{'A'})
|
||||||
@@ -358,9 +358,9 @@ func TestStore_SaveCheckpointState(t *testing.T) {
|
|||||||
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
|
assert.Equal(t, 2*params.BeaconConfig().SlotsPerEpoch, s2.Slot(), "Unexpected state slot")
|
||||||
|
|
||||||
require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))
|
require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r[:]}, [32]byte{'a'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r[:]}, [32]byte{'b'})
|
||||||
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: r[:]})
|
||||||
cp3 := ðpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, fieldparams.RootLength)}
|
cp3 := ðpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, fieldparams.RootLength)}
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
|
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'})))
|
||||||
@@ -438,7 +438,7 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
d := util.HydrateAttestationData(ðpb.AttestationData{})
|
d := util.HydrateAttestationData(ðpb.AttestationData{})
|
||||||
assert.ErrorContains(t, "signed beacon block can't be nil", service.verifyBeaconBlock(ctx, d))
|
require.Equal(t, errBlockNotFoundInCacheOrDB, service.verifyBeaconBlock(ctx, d))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
|
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
|
||||||
@@ -500,7 +500,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot_ProtoArray(t *testing.T) {
|
|||||||
r32, err := b32.Block.HashTreeRoot()
|
r32, err := b32.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 1}, [32]byte{})
|
||||||
b33 := util.NewBeaconBlock()
|
b33 := util.NewBeaconBlock()
|
||||||
b33.Block.Slot = 33
|
b33.Block.Slot = 33
|
||||||
b33.Block.ParentRoot = r32[:]
|
b33.Block.ParentRoot = r32[:]
|
||||||
@@ -535,7 +535,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot_DoublyLinkedTree(t *testing
|
|||||||
r32, err := b32.Block.HashTreeRoot()
|
r32, err := b32.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 1}, [32]byte{})
|
||||||
b33 := util.NewBeaconBlock()
|
b33 := util.NewBeaconBlock()
|
||||||
b33.Block.Slot = 33
|
b33.Block.Slot = 33
|
||||||
b33.Block.ParentRoot = r32[:]
|
b33.Block.ParentRoot = r32[:]
|
||||||
@@ -564,7 +564,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
|
|||||||
r32, err := b32.Block.HashTreeRoot()
|
r32, err := b32.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: r32[:], Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r32[:], Epoch: 1}, [32]byte{})
|
||||||
|
|
||||||
b33 := util.NewBeaconBlock()
|
b33 := util.NewBeaconBlock()
|
||||||
b33.Block.Slot = 33
|
b33.Block.Slot = 33
|
||||||
@@ -591,7 +591,7 @@ func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
|
|||||||
r32, err := b32.Block.HashTreeRoot()
|
r32, err := b32.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: r32[:], Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: r32[:], Epoch: 1}, [32]byte{})
|
||||||
|
|
||||||
b33 := util.NewBeaconBlock()
|
b33 := util.NewBeaconBlock()
|
||||||
b33.Block.Slot = 33
|
b33.Block.Slot = 33
|
||||||
|
|||||||
@@ -16,13 +16,14 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
||||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@@ -88,7 +89,7 @@ var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
|
|||||||
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
|
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
|
||||||
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
|
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
|
||||||
// store.justified_checkpoint = state.current_justified_checkpoint
|
// store.justified_checkpoint = state.current_justified_checkpoint
|
||||||
func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, blockRoot [32]byte) error {
|
func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
|
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
if err := helpers.BeaconBlockIsNil(signed); err != nil {
|
if err := helpers.BeaconBlockIsNil(signed); err != nil {
|
||||||
@@ -113,23 +114,22 @@ func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
isValidPayload, err := s.notifyNewPayload(ctx, preStateVersion, postStateVersion, preStateHeader, postStateHeader, signed)
|
isValidPayload, err := s.notifyNewPayload(ctx, postStateVersion, postStateHeader, signed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not verify new payload")
|
return errors.Wrap(err, "could not verify new payload")
|
||||||
}
|
}
|
||||||
if !isValidPayload {
|
if isValidPayload {
|
||||||
candidate, err := s.optimisticCandidateBlock(ctx, b)
|
if err := s.validateMergeTransitionBlock(ctx, preStateVersion, preStateHeader, signed); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return errors.Wrap(err, "could not check if block is optimistic candidate")
|
|
||||||
}
|
|
||||||
if !candidate {
|
|
||||||
return errNotOptimisticCandidate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState); err != nil {
|
||||||
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, false /* reg sync */); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, signed.Block(), blockRoot, postState); err != nil {
|
||||||
|
return errors.Wrapf(err, "could not insert block %d to fork choice store", signed.Block().Slot())
|
||||||
|
}
|
||||||
|
s.insertSlashingsToForkChoiceStore(ctx, signed.Block().Body().AttesterSlashings())
|
||||||
if isValidPayload {
|
if isValidPayload {
|
||||||
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, blockRoot); err != nil {
|
if err := s.cfg.ForkChoiceStore.SetOptimisticToValid(ctx, blockRoot); err != nil {
|
||||||
return errors.Wrap(err, "could not set optimistic block to valid")
|
return errors.Wrap(err, "could not set optimistic block to valid")
|
||||||
@@ -194,9 +194,19 @@ func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, b
|
|||||||
newFinalized := postState.FinalizedCheckpointEpoch() > finalized.Epoch
|
newFinalized := postState.FinalizedCheckpointEpoch() > finalized.Epoch
|
||||||
if newFinalized {
|
if newFinalized {
|
||||||
s.store.SetPrevFinalizedCheckpt(finalized)
|
s.store.SetPrevFinalizedCheckpt(finalized)
|
||||||
s.store.SetFinalizedCheckpt(postState.FinalizedCheckpoint())
|
cp := postState.FinalizedCheckpoint()
|
||||||
|
h, err := s.getPayloadHash(ctx, cp.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetFinalizedCheckptAndPayloadHash(cp, h)
|
||||||
s.store.SetPrevJustifiedCheckpt(justified)
|
s.store.SetPrevJustifiedCheckpt(justified)
|
||||||
s.store.SetJustifiedCheckpt(postState.CurrentJustifiedCheckpoint())
|
cp = postState.CurrentJustifiedCheckpoint()
|
||||||
|
h, err = s.getPayloadHash(ctx, cp.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetJustifiedCheckptAndPayloadHash(postState.CurrentJustifiedCheckpoint(), h)
|
||||||
}
|
}
|
||||||
|
|
||||||
balances, err := s.justifiedBalances.get(ctx, bytesutil.ToBytes32(justified.Root))
|
balances, err := s.justifiedBalances.get(ctx, bytesutil.ToBytes32(justified.Root))
|
||||||
@@ -208,20 +218,7 @@ func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Warn("Could not update head")
|
log.WithError(err).Warn("Could not update head")
|
||||||
}
|
}
|
||||||
headBlock, err := s.cfg.BeaconDB.Block(ctx, headRoot)
|
s.notifyEngineIfChangedHead(ctx, headRoot)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := s.notifyForkchoiceUpdate(ctx, headState, headBlock.Block(), headRoot, bytesutil.ToBytes32(finalized.Root)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := s.saveHead(ctx, headRoot, headBlock, headState); err != nil {
|
|
||||||
return errors.Wrap(err, "could not save head")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.pruneCanonicalAttsFromPool(ctx, blockRoot, signed); err != nil {
|
if err := s.pruneCanonicalAttsFromPool(ctx, blockRoot, signed); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -317,7 +314,7 @@ func getStateVersionAndPayload(st state.BeaconState) (int, *ethpb.ExecutionPaylo
|
|||||||
return preStateVersion, preStateHeader, nil
|
return preStateVersion, preStateHeader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlock,
|
func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock,
|
||||||
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
|
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
|
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -403,23 +400,16 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
|||||||
|
|
||||||
// blocks have been verified, add them to forkchoice and call the engine
|
// blocks have been verified, add them to forkchoice and call the engine
|
||||||
for i, b := range blks {
|
for i, b := range blks {
|
||||||
s.saveInitSyncBlock(blockRoots[i], b)
|
|
||||||
isValidPayload, err := s.notifyNewPayload(ctx,
|
isValidPayload, err := s.notifyNewPayload(ctx,
|
||||||
preVersionAndHeaders[i].version,
|
|
||||||
postVersionAndHeaders[i].version,
|
postVersionAndHeaders[i].version,
|
||||||
preVersionAndHeaders[i].header,
|
|
||||||
postVersionAndHeaders[i].header, b)
|
postVersionAndHeaders[i].header, b)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if !isValidPayload {
|
if isValidPayload {
|
||||||
candidate, err := s.optimisticCandidateBlock(ctx, b.Block())
|
if err := s.validateMergeTransitionBlock(ctx, preVersionAndHeaders[i].version,
|
||||||
if err != nil {
|
preVersionAndHeaders[i].header, b); err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "could not check if block is optimistic candidate")
|
return nil, nil, err
|
||||||
}
|
|
||||||
if !candidate {
|
|
||||||
return nil, nil, errNotOptimisticCandidate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +421,9 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
|||||||
return nil, nil, errors.Wrap(err, "could not set optimistic block to valid")
|
return nil, nil, errors.Wrap(err, "could not set optimistic block to valid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.saveInitSyncBlock(blockRoots[i], b)
|
||||||
if _, err := s.notifyForkchoiceUpdate(ctx, preState, b.Block(), blockRoots[i], bytesutil.ToBytes32(fCheckpoints[i].Root)); err != nil {
|
if err = s.handleBlockAfterBatchVerify(ctx, b, blockRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
|
||||||
|
tracing.AnnotateError(span, err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,6 +439,14 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
|||||||
if err := s.cfg.StateGen.SaveState(ctx, lastBR, preState); err != nil {
|
if err := s.cfg.StateGen.SaveState(ctx, lastBR, preState); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
arg := ¬ifyForkchoiceUpdateArg{
|
||||||
|
headState: preState,
|
||||||
|
headRoot: lastBR,
|
||||||
|
headBlock: lastB.Block(),
|
||||||
|
}
|
||||||
|
if _, err := s.notifyForkchoiceUpdate(ctx, arg); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
if err := s.saveHeadNoDB(ctx, lastB, lastBR, preState); err != nil {
|
if err := s.saveHeadNoDB(ctx, lastB, lastBR, preState); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -456,7 +455,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
|||||||
|
|
||||||
// handles a block after the block's batch has been verified, where we can save blocks
|
// handles a block after the block's batch has been verified, where we can save blocks
|
||||||
// their state summaries and split them off to relative hot/cold storage.
|
// their state summaries and split them off to relative hot/cold storage.
|
||||||
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed block.SignedBeaconBlock,
|
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interfaces.SignedBeaconBlock,
|
||||||
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||||
|
|
||||||
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{
|
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{
|
||||||
@@ -494,7 +493,11 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed block.
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.store.SetPrevFinalizedCheckpt(finalized)
|
s.store.SetPrevFinalizedCheckpt(finalized)
|
||||||
s.store.SetFinalizedCheckpt(fCheckpoint)
|
h, err := s.getPayloadHash(ctx, fCheckpoint.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetFinalizedCheckptAndPayloadHash(fCheckpoint, h)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -505,15 +508,15 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState state.Beaco
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if postState.Slot()+1 == s.nextEpochBoundarySlot {
|
if postState.Slot()+1 == s.nextEpochBoundarySlot {
|
||||||
// Update caches for the next epoch at epoch boundary slot - 1.
|
|
||||||
if err := helpers.UpdateCommitteeCache(postState, coreTime.NextEpoch(postState)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
copied := postState.Copy()
|
copied := postState.Copy()
|
||||||
copied, err := transition.ProcessSlots(ctx, copied, copied.Slot()+1)
|
copied, err := transition.ProcessSlots(ctx, copied, copied.Slot()+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// Update caches for the next epoch at epoch boundary slot - 1.
|
||||||
|
if err := helpers.UpdateCommitteeCache(copied, coreTime.CurrentEpoch(copied)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := helpers.UpdateProposerIndicesInCache(ctx, copied); err != nil {
|
if err := helpers.UpdateProposerIndicesInCache(ctx, copied); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -542,7 +545,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState state.Beaco
|
|||||||
|
|
||||||
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
|
// 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.
|
// to gain information on the most current chain.
|
||||||
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk block.BeaconBlock, root [32]byte,
|
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock, root [32]byte,
|
||||||
st state.BeaconState) error {
|
st state.BeaconState) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.insertBlockAndAttestationsToForkChoiceStore")
|
ctx, span := trace.StartSpan(ctx, "blockChain.insertBlockAndAttestationsToForkChoiceStore")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -567,7 +570,7 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk block.BeaconBlock,
|
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock,
|
||||||
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||||
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
|
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -584,7 +587,18 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk block.Be
|
|||||||
fCheckpoint.Epoch)
|
fCheckpoint.Epoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBlockPayloadHash(blk block.BeaconBlock) ([32]byte, error) {
|
// Inserts attester slashing indices to fork choice store.
|
||||||
|
// To call this function, it's caller's responsibility to ensure the slashing object is valid.
|
||||||
|
func (s *Service) insertSlashingsToForkChoiceStore(ctx context.Context, slashings []*ethpb.AttesterSlashing) {
|
||||||
|
for _, slashing := range slashings {
|
||||||
|
indices := blocks.SlashableAttesterIndices(slashing)
|
||||||
|
for _, index := range indices {
|
||||||
|
s.ForkChoicer().InsertSlashedIndex(ctx, types.ValidatorIndex(index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBlockPayloadHash(blk interfaces.BeaconBlock) ([32]byte, error) {
|
||||||
payloadHash := [32]byte{}
|
payloadHash := [32]byte{}
|
||||||
if blocks.IsPreBellatrixVersion(blk.Version()) {
|
if blocks.IsPreBellatrixVersion(blk.Version()) {
|
||||||
return payloadHash, nil
|
return payloadHash, nil
|
||||||
@@ -598,26 +612,21 @@ func getBlockPayloadHash(blk block.BeaconBlock) ([32]byte, error) {
|
|||||||
|
|
||||||
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
|
// 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.
|
// 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 block.SignedBeaconBlock, st state.BeaconState, initSync bool) error {
|
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock, st state.BeaconState) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
|
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
if initSync {
|
if err := s.cfg.BeaconDB.SaveBlock(ctx, b); err != nil {
|
||||||
s.saveInitSyncBlock(r, b)
|
|
||||||
} 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())
|
return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot())
|
||||||
}
|
}
|
||||||
if err := s.cfg.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")
|
return errors.Wrap(err, "could not save state")
|
||||||
}
|
}
|
||||||
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block(), r, st); err != nil {
|
|
||||||
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block().Slot())
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This removes the attestations from the mem pool. It will only remove the attestations if input root `r` is canonical,
|
// This removes the attestations from the mem pool. It will only remove the attestations if input root `r` is canonical,
|
||||||
// meaning the block `b` is part of the canonical chain.
|
// meaning the block `b` is part of the canonical chain.
|
||||||
func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b block.SignedBeaconBlock) error {
|
func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock) error {
|
||||||
if !features.Get().CorrectlyPruneCanonicalAtts {
|
if !features.Get().CorrectlyPruneCanonicalAtts {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -644,3 +653,36 @@ func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateMergeTransitionBlock validates the merge transition block.
|
||||||
|
func (s *Service) validateMergeTransitionBlock(ctx context.Context, stateVersion int, stateHeader *ethpb.ExecutionPayloadHeader, blk interfaces.SignedBeaconBlock) error {
|
||||||
|
// Skip validation if block is older than Bellatrix.
|
||||||
|
if blocks.IsPreBellatrixVersion(blk.Block().Version()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip validation if block has an empty payload.
|
||||||
|
payload, err := blk.Block().Body().ExecutionPayload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if blocks.IsEmptyPayload(payload) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle case where pre-state is Altair but block contains payload.
|
||||||
|
// To reach here, the block must have contained a valid payload.
|
||||||
|
if blocks.IsPreBellatrixVersion(stateVersion) {
|
||||||
|
return s.validateMergeBlock(ctx, blk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip validation if the block is not a merge transition block.
|
||||||
|
atTransition, err := blocks.IsMergeTransitionBlockUsingPreStatePayloadHeader(stateHeader, blk.Block().Body())
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not check if merge block is terminal")
|
||||||
|
}
|
||||||
|
if !atTransition {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.validateMergeBlock(ctx, blk)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,14 +6,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
mathutil "github.com/prysmaticlabs/prysm/math"
|
||||||
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
@@ -26,7 +27,7 @@ func (s *Service) CurrentSlot() types.Slot {
|
|||||||
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
|
// 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
|
// to retrieve the state in DB. It verifies the pre state's validity and the incoming block
|
||||||
// is in the correct time window.
|
// is in the correct time window.
|
||||||
func (s *Service) getBlockPreState(ctx context.Context, b block.BeaconBlock) (state.BeaconState, error) {
|
func (s *Service) getBlockPreState(ctx context.Context, b interfaces.BeaconBlock) (state.BeaconState, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
|
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ func (s *Service) getBlockPreState(ctx context.Context, b block.BeaconBlock) (st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verifyBlkPreState validates input block has a valid pre-state.
|
// verifyBlkPreState validates input block has a valid pre-state.
|
||||||
func (s *Service) verifyBlkPreState(ctx context.Context, b block.BeaconBlock) error {
|
func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBlock) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
|
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b block.BeaconBlock) er
|
|||||||
return errors.New("could not reconstruct parent state")
|
return errors.New("could not reconstruct parent state")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot())); err != nil {
|
if err := s.VerifyFinalizedBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +87,10 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b block.BeaconBlock) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyBlkDescendant validates input block root is a descendant of the
|
// VerifyFinalizedBlkDescendant validates if input block root is a descendant of the
|
||||||
// current finalized block root.
|
// current finalized block root.
|
||||||
func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error {
|
func (s *Service) VerifyFinalizedBlkDescendant(ctx context.Context, root [32]byte) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.VerifyBlkDescendant")
|
ctx, span := trace.StartSpan(ctx, "blockChain.VerifyFinalizedBlkDescendant")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
finalized := s.store.FinalizedCheckpt()
|
finalized := s.store.FinalizedCheckpt()
|
||||||
if finalized == nil {
|
if finalized == nil {
|
||||||
@@ -124,7 +125,7 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
|
|||||||
|
|
||||||
// verifyBlkFinalizedSlot validates input block is not less than or equal
|
// verifyBlkFinalizedSlot validates input block is not less than or equal
|
||||||
// to current finalized slot.
|
// to current finalized slot.
|
||||||
func (s *Service) verifyBlkFinalizedSlot(b block.BeaconBlock) error {
|
func (s *Service) verifyBlkFinalizedSlot(b interfaces.BeaconBlock) error {
|
||||||
finalized := s.store.FinalizedCheckpt()
|
finalized := s.store.FinalizedCheckpt()
|
||||||
if finalized == nil {
|
if finalized == nil {
|
||||||
return errNilFinalizedInStore
|
return errNilFinalizedInStore
|
||||||
@@ -207,7 +208,11 @@ func (s *Service) updateJustified(ctx context.Context, state state.ReadOnlyBeaco
|
|||||||
return errNilJustifiedInStore
|
return errNilJustifiedInStore
|
||||||
}
|
}
|
||||||
s.store.SetPrevJustifiedCheckpt(justified)
|
s.store.SetPrevJustifiedCheckpt(justified)
|
||||||
s.store.SetJustifiedCheckpt(cpt)
|
h, err := s.getPayloadHash(ctx, cpt.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetJustifiedCheckptAndPayloadHash(cpt, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -226,7 +231,11 @@ func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpo
|
|||||||
if err := s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cp); err != nil {
|
if err := s.cfg.BeaconDB.SaveJustifiedCheckpoint(ctx, cp); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.store.SetJustifiedCheckpt(cp)
|
h, err := s.getPayloadHash(ctx, cp.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.store.SetJustifiedCheckptAndPayloadHash(cp, h)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -316,17 +325,9 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot)
|
|||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
signed, err := s.cfg.BeaconDB.Block(ctx, r)
|
signed, err := s.getBlock(ctx, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get ancestor block")
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
if s.hasInitSyncBlock(r) {
|
|
||||||
signed = s.getInitSyncBlock(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
|
|
||||||
return nil, errors.New("nil block")
|
|
||||||
}
|
}
|
||||||
b := signed.Block()
|
b := signed.Block()
|
||||||
if b.Slot() == slot || b.Slot() < slot {
|
if b.Slot() == slot || b.Slot() < slot {
|
||||||
@@ -338,9 +339,9 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot)
|
|||||||
|
|
||||||
// This retrieves missing blocks from DB (ie. the blocks that couldn't be received over sync) and inserts them to fork choice store.
|
// This retrieves missing blocks from DB (ie. the blocks that couldn't be received over sync) and inserts them to fork choice store.
|
||||||
// This is useful for block tree visualizer and additional vote accounting.
|
// This is useful for block tree visualizer and additional vote accounting.
|
||||||
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk block.BeaconBlock,
|
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk interfaces.BeaconBlock,
|
||||||
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||||
pendingNodes := make([]block.BeaconBlock, 0)
|
pendingNodes := make([]interfaces.BeaconBlock, 0)
|
||||||
pendingRoots := make([][32]byte, 0)
|
pendingRoots := make([][32]byte, 0)
|
||||||
|
|
||||||
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
|
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
|
||||||
@@ -402,10 +403,17 @@ func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) e
|
|||||||
// We update the cache up to the last deposit index in the finalized block's 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
|
// 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.
|
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
|
||||||
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
|
eth1DepositIndex, err := mathutil.Int(finalizedState.Eth1DepositIndex())
|
||||||
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not cast eth1 deposit index")
|
||||||
|
}
|
||||||
|
// The deposit index in the state is always the index of the next deposit
|
||||||
|
// to be included(rather than the last one to be processed). This was most likely
|
||||||
|
// done as the state cannot represent signed integers.
|
||||||
|
eth1DepositIndex -= 1
|
||||||
|
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(eth1DepositIndex))
|
||||||
// Deposit proofs are only used during state transition and can be safely removed to save space.
|
// 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 {
|
if err = s.cfg.DepositCache.PruneProofs(ctx, int64(eth1DepositIndex)); err != nil {
|
||||||
return errors.Wrap(err, "could not prune deposit proofs")
|
return errors.Wrap(err, "could not prune deposit proofs")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -5,35 +5,42 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
forkchoicetypes "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/types"
|
forkchoicetypes "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/types"
|
||||||
|
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
prysmTime "github.com/prysmaticlabs/prysm/time"
|
prysmTime "github.com/prysmaticlabs/prysm/time"
|
||||||
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStore_OnBlock_ProtoArray(t *testing.T) {
|
func TestStore_OnBlock_ProtoArray(t *testing.T) {
|
||||||
@@ -124,9 +131,9 @@ func TestStore_OnBlock_ProtoArray(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: validGenesisRoot[:]}, [32]byte{'a'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: roots[0]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: roots[0]}, [32]byte{'b'})
|
||||||
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
||||||
|
|
||||||
root, err := tt.blk.Block.HashTreeRoot()
|
root, err := tt.blk.Block.HashTreeRoot()
|
||||||
@@ -227,9 +234,9 @@ func TestStore_OnBlock_DoublyLinkedTree(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: validGenesisRoot[:]}, [32]byte{'a'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: roots[0]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: roots[0]}, [32]byte{'b'})
|
||||||
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
service.store.SetPrevFinalizedCheckpt(ðpb.Checkpoint{Root: validGenesisRoot[:]})
|
||||||
|
|
||||||
root, err := tt.blk.Block.HashTreeRoot()
|
root, err := tt.blk.Block.HashTreeRoot()
|
||||||
@@ -284,7 +291,8 @@ func TestStore_OnBlockBatch_ProtoArray(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'b'})
|
||||||
|
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||||
@@ -295,7 +303,7 @@ func TestStore_OnBlockBatch_ProtoArray(t *testing.T) {
|
|||||||
|
|
||||||
bState := st.Copy()
|
bState := st.Copy()
|
||||||
|
|
||||||
var blks []block.SignedBeaconBlock
|
var blks []interfaces.SignedBeaconBlock
|
||||||
var blkRoots [][32]byte
|
var blkRoots [][32]byte
|
||||||
var firstState state.BeaconState
|
var firstState state.BeaconState
|
||||||
for i := 1; i < 10; i++ {
|
for i := 1; i < 10; i++ {
|
||||||
@@ -348,7 +356,8 @@ func TestStore_OnBlockBatch_DoublyLinkedTree(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'b'})
|
||||||
|
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||||
@@ -359,7 +368,7 @@ func TestStore_OnBlockBatch_DoublyLinkedTree(t *testing.T) {
|
|||||||
|
|
||||||
bState := st.Copy()
|
bState := st.Copy()
|
||||||
|
|
||||||
var blks []block.SignedBeaconBlock
|
var blks []interfaces.SignedBeaconBlock
|
||||||
var blkRoots [][32]byte
|
var blkRoots [][32]byte
|
||||||
var firstState state.BeaconState
|
var firstState state.BeaconState
|
||||||
for i := 1; i < 10; i++ {
|
for i := 1; i < 10; i++ {
|
||||||
@@ -410,13 +419,15 @@ func TestStore_OnBlockBatch_NotifyNewPayload(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'b'})
|
||||||
|
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
service.saveInitSyncBlock(gRoot, wsb)
|
service.saveInitSyncBlock(gRoot, wsb)
|
||||||
st, keys := util.DeterministicGenesisState(t, 64)
|
st, keys := util.DeterministicGenesisState(t, 64)
|
||||||
bState := st.Copy()
|
bState := st.Copy()
|
||||||
|
|
||||||
var blks []block.SignedBeaconBlock
|
var blks []interfaces.SignedBeaconBlock
|
||||||
var blkRoots [][32]byte
|
var blkRoots [][32]byte
|
||||||
var firstState state.BeaconState
|
var firstState state.BeaconState
|
||||||
blkCount := 4
|
blkCount := 4
|
||||||
@@ -479,7 +490,7 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
|
|||||||
|
|
||||||
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
||||||
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: lastJustifiedRoot[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: lastJustifiedRoot[:]}, [32]byte{'a'})
|
||||||
update, err = service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
update, err = service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, update, "Should be able to update justified")
|
assert.Equal(t, true, update, "Should be able to update justified")
|
||||||
@@ -511,7 +522,7 @@ func TestShouldUpdateJustified_ReturnFalse_ProtoArray(t *testing.T) {
|
|||||||
|
|
||||||
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
||||||
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: lastJustifiedRoot[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: lastJustifiedRoot[:]}, [32]byte{'a'})
|
||||||
|
|
||||||
update, err := service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
update, err := service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -544,7 +555,7 @@ func TestShouldUpdateJustified_ReturnFalse_DoublyLinkedTree(t *testing.T) {
|
|||||||
|
|
||||||
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
||||||
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: lastJustifiedRoot[:]})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: lastJustifiedRoot[:]}, [32]byte{'a'})
|
||||||
|
|
||||||
update, err := service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
update, err := service.shouldUpdateCurrentJustified(ctx, ðpb.Checkpoint{Root: newJustifiedRoot[:]})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -572,7 +583,7 @@ func TestCachedPreState_CanGetFromStateSummary_ProtoArray(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -583,7 +594,9 @@ func TestCachedPreState_CanGetFromStateSummary_ProtoArray(t *testing.T) {
|
|||||||
b.Block.ParentRoot = gRoot[:]
|
b.Block.ParentRoot = gRoot[:]
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{Slot: 1, Root: gRoot[:]}))
|
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.cfg.StateGen.SaveState(ctx, gRoot, s))
|
||||||
require.NoError(t, service.verifyBlkPreState(ctx, wrapper.WrappedPhase0BeaconBlock(b.Block)))
|
wb, err := wrapper.WrappedBeaconBlock(b.Block)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, service.verifyBlkPreState(ctx, wb))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCachedPreState_CanGetFromStateSummary_DoublyLinkedTree(t *testing.T) {
|
func TestCachedPreState_CanGetFromStateSummary_DoublyLinkedTree(t *testing.T) {
|
||||||
@@ -607,7 +620,7 @@ func TestCachedPreState_CanGetFromStateSummary_DoublyLinkedTree(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -618,7 +631,9 @@ func TestCachedPreState_CanGetFromStateSummary_DoublyLinkedTree(t *testing.T) {
|
|||||||
b.Block.ParentRoot = gRoot[:]
|
b.Block.ParentRoot = gRoot[:]
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{Slot: 1, Root: gRoot[:]}))
|
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.cfg.StateGen.SaveState(ctx, gRoot, s))
|
||||||
require.NoError(t, service.verifyBlkPreState(ctx, wrapper.WrappedPhase0BeaconBlock(b.Block)))
|
wb, err := wrapper.WrappedBeaconBlock(b.Block)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, service.verifyBlkPreState(ctx, wb))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
||||||
@@ -639,7 +654,7 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
|||||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
gRoot, err := genesis.Block.HashTreeRoot()
|
gRoot, err := genesis.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -647,8 +662,10 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
|||||||
|
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
b.Block.Slot = 1
|
b.Block.Slot = 1
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
err = service.verifyBlkPreState(ctx, wrapper.WrappedPhase0BeaconBlock(b.Block))
|
wb, err := wrapper.WrappedBeaconBlock(b.Block)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = service.verifyBlkPreState(ctx, wb)
|
||||||
wanted := "could not reconstruct parent state"
|
wanted := "could not reconstruct parent state"
|
||||||
assert.ErrorContains(t, wanted, err)
|
assert.ErrorContains(t, wanted, err)
|
||||||
|
|
||||||
@@ -680,7 +697,7 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
|
|||||||
require.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
require.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||||
r, err := signedBlock.Block.HashTreeRoot()
|
r, err := signedBlock.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetJustifiedCheckpt(ðpb.Checkpoint{Root: []byte{'A'}})
|
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: []byte{'A'}}, [32]byte{'a'})
|
||||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: []byte{'A'}})
|
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: []byte{'A'}})
|
||||||
st, err := util.NewBeaconState()
|
st, err := util.NewBeaconState()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -712,7 +729,7 @@ func TestFillForkChoiceMissingBlocks_CanSave_ProtoArray(t *testing.T) {
|
|||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: make([]byte, 32)})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: make([]byte, 32)}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -757,7 +774,7 @@ func TestFillForkChoiceMissingBlocks_CanSave_DoublyLinkedTree(t *testing.T) {
|
|||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: make([]byte, 32)})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: make([]byte, 32)}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -803,7 +820,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch_ProtoArray(t *testing.T) {
|
|||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: make([]byte, 32)})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: make([]byte, 32)}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -852,7 +869,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch_DoublyLinkedTree(t *testing.T) {
|
|||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: make([]byte, 32)})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: make([]byte, 32)}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -902,7 +919,7 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized_ProtoArray(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
|
||||||
// Set finalized epoch to 1.
|
// Set finalized epoch to 1.
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 1}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -963,7 +980,7 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized_DoublyLinkedTree(t *testing
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
service.cfg.ForkChoiceStore = doublylinkedtree.New(0, 0)
|
||||||
// Set finalized epoch to 1.
|
// Set finalized epoch to 1.
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 1})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 1}, [32]byte{})
|
||||||
|
|
||||||
genesisStateRoot := [32]byte{}
|
genesisStateRoot := [32]byte{}
|
||||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||||
@@ -1339,8 +1356,8 @@ func TestVerifyBlkDescendant(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
service, err := NewService(ctx, opts...)
|
service, err := NewService(ctx, opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: tt.args.finalizedRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: tt.args.finalizedRoot[:]}, [32]byte{})
|
||||||
err = service.VerifyBlkDescendant(ctx, tt.args.parentRoot)
|
err = service.VerifyFinalizedBlkDescendant(ctx, tt.args.parentRoot)
|
||||||
if tt.wantedErr != "" {
|
if tt.wantedErr != "" {
|
||||||
assert.ErrorContains(t, tt.wantedErr, err)
|
assert.ErrorContains(t, tt.wantedErr, err)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@@ -1367,7 +1384,7 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
|
|||||||
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, beaconState, gRoot))
|
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, beaconState, gRoot))
|
||||||
service.originBlockRoot = gRoot
|
service.originBlockRoot = gRoot
|
||||||
currentCp := ðpb.Checkpoint{Epoch: 1}
|
currentCp := ðpb.Checkpoint{Epoch: 1}
|
||||||
service.store.SetJustifiedCheckpt(currentCp)
|
service.store.SetJustifiedCheckptAndPayloadHash(currentCp, [32]byte{'a'})
|
||||||
newCp := ðpb.Checkpoint{Epoch: 2, Root: gRoot[:]}
|
newCp := ðpb.Checkpoint{Epoch: 2, Root: gRoot[:]}
|
||||||
|
|
||||||
require.NoError(t, service.updateJustifiedInitSync(ctx, newCp))
|
require.NoError(t, service.updateJustifiedInitSync(ctx, newCp))
|
||||||
@@ -1428,7 +1445,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
|
|
||||||
testState := gs.Copy()
|
testState := gs.Copy()
|
||||||
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
|
for i := types.Slot(1); i <= 4*params.BeaconConfig().SlotsPerEpoch; i++ {
|
||||||
@@ -1482,7 +1499,7 @@ func TestOnBlock_CallNewPayloadAndForkchoiceUpdated(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
|
|
||||||
testState := gs.Copy()
|
testState := gs.Copy()
|
||||||
for i := types.Slot(1); i < params.BeaconConfig().SlotsPerEpoch; i++ {
|
for i := types.Slot(1); i < params.BeaconConfig().SlotsPerEpoch; i++ {
|
||||||
@@ -1513,9 +1530,10 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
service.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
gs = gs.Copy()
|
gs = gs.Copy()
|
||||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10}))
|
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10}))
|
||||||
|
assert.NoError(t, gs.SetEth1DepositIndex(8))
|
||||||
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
||||||
zeroSig := [96]byte{}
|
zeroSig := [96]byte{}
|
||||||
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
|
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
|
||||||
@@ -1529,8 +1547,64 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
|
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
|
||||||
fDeposits := depositCache.FinalizedDeposits(ctx)
|
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||||
assert.Equal(t, 9, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||||
deps := depositCache.AllDeposits(ctx, big.NewInt(109))
|
deps := depositCache.AllDeposits(ctx, big.NewInt(107))
|
||||||
|
for _, d := range deps {
|
||||||
|
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
opts := testServiceOptsWithDB(t)
|
||||||
|
depositCache, err := depositcache.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
opts = append(opts, WithDepositCache(depositCache))
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
gs, _ := util.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.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{})
|
||||||
|
gs = gs.Copy()
|
||||||
|
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 7}))
|
||||||
|
assert.NoError(t, gs.SetEth1DepositIndex(6))
|
||||||
|
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
||||||
|
gs2 := gs.Copy()
|
||||||
|
assert.NoError(t, gs2.SetEth1Data(ðpb.Eth1Data{DepositCount: 15}))
|
||||||
|
assert.NoError(t, gs2.SetEth1DepositIndex(13))
|
||||||
|
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}, gs2))
|
||||||
|
zeroSig := [96]byte{}
|
||||||
|
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
|
||||||
|
root := []byte(strconv.Itoa(int(i)))
|
||||||
|
assert.NoError(t, depositCache.InsertDeposit(ctx, ðpb.Deposit{Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.FromBytes48([fieldparams.BLSPubkeyLength]byte{}),
|
||||||
|
WithdrawalCredentials: params.BeaconConfig().ZeroHash[:],
|
||||||
|
Amount: 0,
|
||||||
|
Signature: zeroSig[:],
|
||||||
|
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
|
||||||
|
}
|
||||||
|
// Insert 3 deposits before hand.
|
||||||
|
depositCache.InsertFinalizedDeposits(ctx, 2)
|
||||||
|
|
||||||
|
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
|
||||||
|
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||||
|
assert.Equal(t, 5, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||||
|
|
||||||
|
deps := depositCache.AllDeposits(ctx, big.NewInt(105))
|
||||||
|
for _, d := range deps {
|
||||||
|
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert New Finalized State with higher deposit count.
|
||||||
|
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}))
|
||||||
|
fDeposits = depositCache.FinalizedDeposits(ctx)
|
||||||
|
assert.Equal(t, 12, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||||
|
deps = depositCache.AllDeposits(ctx, big.NewInt(112))
|
||||||
for _, d := range deps {
|
for _, d := range deps {
|
||||||
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||||
}
|
}
|
||||||
@@ -1635,3 +1709,266 @@ func Test_getStateVersionAndPayload(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||||
|
cfg := params.BeaconConfig()
|
||||||
|
cfg.TerminalTotalDifficulty = "2"
|
||||||
|
cfg.TerminalBlockHash = params.BeaconConfig().ZeroHash
|
||||||
|
params.OverrideBeaconConfig(cfg)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
fcs := protoarray.New(0, 0, [32]byte{'a'})
|
||||||
|
opts := []Option{
|
||||||
|
WithDatabase(beaconDB),
|
||||||
|
WithStateGen(stategen.New(beaconDB)),
|
||||||
|
WithForkChoiceStore(fcs),
|
||||||
|
WithProposerIdsCache(cache.NewProposerPayloadIDsCache()),
|
||||||
|
}
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
stateVersion int
|
||||||
|
header *ethpb.ExecutionPayloadHeader
|
||||||
|
payload *enginev1.ExecutionPayload
|
||||||
|
errString string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "state older than Bellatrix, nil payload",
|
||||||
|
stateVersion: 1,
|
||||||
|
payload: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state older than Bellatrix, empty payload",
|
||||||
|
stateVersion: 1,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: make([]byte, fieldparams.RootLength),
|
||||||
|
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||||
|
StateRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||||
|
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||||
|
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||||
|
BlockHash: make([]byte, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state older than Bellatrix, non empty payload",
|
||||||
|
stateVersion: 1,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state is Bellatrix, nil payload",
|
||||||
|
stateVersion: 2,
|
||||||
|
payload: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state is Bellatrix, empty payload",
|
||||||
|
stateVersion: 2,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: make([]byte, fieldparams.RootLength),
|
||||||
|
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||||
|
StateRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||||
|
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||||
|
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||||
|
BlockHash: make([]byte, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state is Bellatrix, non empty payload, empty header",
|
||||||
|
stateVersion: 2,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
header: ðpb.ExecutionPayloadHeader{
|
||||||
|
ParentHash: make([]byte, fieldparams.RootLength),
|
||||||
|
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||||
|
StateRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||||
|
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||||
|
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||||
|
BlockHash: make([]byte, fieldparams.RootLength),
|
||||||
|
TransactionsRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state is Bellatrix, non empty payload, non empty header",
|
||||||
|
stateVersion: 2,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
header: ðpb.ExecutionPayloadHeader{
|
||||||
|
BlockNumber: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "state is Bellatrix, non empty payload, nil header",
|
||||||
|
stateVersion: 2,
|
||||||
|
payload: &enginev1.ExecutionPayload{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||||
|
},
|
||||||
|
errString: "nil header or block body",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
e := &mockPOW.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
|
||||||
|
e.BlockByHashMap[[32]byte{'a'}] = &enginev1.ExecutionBlock{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'b'}, fieldparams.RootLength),
|
||||||
|
TotalDifficulty: "0x2",
|
||||||
|
}
|
||||||
|
e.BlockByHashMap[[32]byte{'b'}] = &enginev1.ExecutionBlock{
|
||||||
|
ParentHash: bytesutil.PadTo([]byte{'3'}, fieldparams.RootLength),
|
||||||
|
TotalDifficulty: "0x1",
|
||||||
|
}
|
||||||
|
service.cfg.ExecutionEngineCaller = e
|
||||||
|
b := util.HydrateSignedBeaconBlockBellatrix(ðpb.SignedBeaconBlockBellatrix{})
|
||||||
|
b.Block.Body.ExecutionPayload = tt.payload
|
||||||
|
blk, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = service.validateMergeTransitionBlock(ctx, tt.stateVersion, tt.header, blk)
|
||||||
|
if tt.errString != "" {
|
||||||
|
require.ErrorContains(t, tt.errString, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestService_insertSlashingsToForkChoiceStore(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
fcs := protoarray.New(0, 0, [32]byte{'a'})
|
||||||
|
opts := []Option{
|
||||||
|
WithDatabase(beaconDB),
|
||||||
|
WithStateGen(stategen.New(beaconDB)),
|
||||||
|
WithForkChoiceStore(fcs),
|
||||||
|
WithProposerIdsCache(cache.NewProposerPayloadIDsCache()),
|
||||||
|
}
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
beaconState, privKeys := util.DeterministicGenesisState(t, 100)
|
||||||
|
att1 := util.HydrateIndexedAttestation(ðpb.IndexedAttestation{
|
||||||
|
Data: ðpb.AttestationData{
|
||||||
|
Source: ðpb.Checkpoint{Epoch: 1},
|
||||||
|
},
|
||||||
|
AttestingIndices: []uint64{0, 1},
|
||||||
|
})
|
||||||
|
domain, err := signing.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorsRoot())
|
||||||
|
require.NoError(t, err)
|
||||||
|
signingRoot, err := signing.ComputeSigningRoot(att1.Data, domain)
|
||||||
|
assert.NoError(t, err, "Could not get signing root of beacon block header")
|
||||||
|
sig0 := privKeys[0].Sign(signingRoot[:])
|
||||||
|
sig1 := privKeys[1].Sign(signingRoot[:])
|
||||||
|
aggregateSig := bls.AggregateSignatures([]bls.Signature{sig0, sig1})
|
||||||
|
att1.Signature = aggregateSig.Marshal()
|
||||||
|
|
||||||
|
att2 := util.HydrateIndexedAttestation(ðpb.IndexedAttestation{
|
||||||
|
AttestingIndices: []uint64{0, 1},
|
||||||
|
})
|
||||||
|
signingRoot, err = signing.ComputeSigningRoot(att2.Data, domain)
|
||||||
|
assert.NoError(t, err, "Could not get signing root of beacon block header")
|
||||||
|
sig0 = privKeys[0].Sign(signingRoot[:])
|
||||||
|
sig1 = privKeys[1].Sign(signingRoot[:])
|
||||||
|
aggregateSig = bls.AggregateSignatures([]bls.Signature{sig0, sig1})
|
||||||
|
att2.Signature = aggregateSig.Marshal()
|
||||||
|
slashings := []*ethpb.AttesterSlashing{
|
||||||
|
{
|
||||||
|
Attestation_1: att1,
|
||||||
|
Attestation_2: att2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
b := util.NewBeaconBlock()
|
||||||
|
b.Block.Body.AttesterSlashings = slashings
|
||||||
|
wb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
service.insertSlashingsToForkChoiceStore(ctx, wb.Block().Body().AttesterSlashings())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnBlock_ProcessBlocksParallel(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
beaconDB := testDB.SetupDB(t)
|
||||||
|
fcs := protoarray.New(0, 0, [32]byte{'a'})
|
||||||
|
depositCache, err := depositcache.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
opts := []Option{
|
||||||
|
WithDatabase(beaconDB),
|
||||||
|
WithStateGen(stategen.New(beaconDB)),
|
||||||
|
WithForkChoiceStore(fcs),
|
||||||
|
WithDepositCache(depositCache),
|
||||||
|
WithStateNotifier(&mock.MockStateNotifier{}),
|
||||||
|
}
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
gs, keys := util.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.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
|
|
||||||
|
blk1, err := util.GenerateFullBlock(gs, keys, util.DefaultBlockGenConfig(), 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r1, err := blk1.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb1, err := wrapper.WrappedSignedBeaconBlock(blk1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
blk2, err := util.GenerateFullBlock(gs, keys, util.DefaultBlockGenConfig(), 2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r2, err := blk2.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb2, err := wrapper.WrappedSignedBeaconBlock(blk2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
blk3, err := util.GenerateFullBlock(gs, keys, util.DefaultBlockGenConfig(), 3)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r3, err := blk3.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb3, err := wrapper.WrappedSignedBeaconBlock(blk3)
|
||||||
|
require.NoError(t, err)
|
||||||
|
blk4, err := util.GenerateFullBlock(gs, keys, util.DefaultBlockGenConfig(), 4)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r4, err := blk4.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
wsb4, err := wrapper.WrappedSignedBeaconBlock(blk4)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
logHook := logTest.NewGlobal()
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(4)
|
||||||
|
go func() {
|
||||||
|
require.NoError(t, service.onBlock(ctx, wsb1, r1))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
require.NoError(t, service.onBlock(ctx, wsb2, r2))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
require.NoError(t, service.onBlock(ctx, wsb3, r3))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
require.NoError(t, service.onBlock(ctx, wsb4, r4))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
require.LogsDoNotContain(t, logHook, "New head does not exist in DB. Do nothing")
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.DeleteBlock(ctx, r1))
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.DeleteBlock(ctx, r2))
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.DeleteBlock(ctx, r3))
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.DeleteBlock(ctx, r4))
|
||||||
|
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'a'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,27 +28,10 @@ type AttestationStateFetcher interface {
|
|||||||
// AttestationReceiver interface defines the methods of chain service receive and processing new attestations.
|
// AttestationReceiver interface defines the methods of chain service receive and processing new attestations.
|
||||||
type AttestationReceiver interface {
|
type AttestationReceiver interface {
|
||||||
AttestationStateFetcher
|
AttestationStateFetcher
|
||||||
ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error
|
|
||||||
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
|
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
|
||||||
VerifyFinalizedConsistency(ctx context.Context, root []byte) error
|
VerifyFinalizedConsistency(ctx context.Context, root []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveAttestationNoPubsub is a function that defines the operations that are performed on
|
|
||||||
// attestation that is received from regular sync. The operations consist of:
|
|
||||||
// 1. Validate attestation, update validator's latest vote
|
|
||||||
// 2. Apply fork choice to the processed attestation
|
|
||||||
// 3. Save latest head info
|
|
||||||
func (s *Service) ReceiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error {
|
|
||||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.ReceiveAttestationNoPubsub")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if err := s.OnAttestation(ctx, att); err != nil {
|
|
||||||
return errors.Wrap(err, "could not process attestation")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AttestationTargetState returns the pre state of attestation.
|
// AttestationTargetState returns the pre state of attestation.
|
||||||
func (s *Service) AttestationTargetState(ctx context.Context, target *ethpb.Checkpoint) (state.BeaconState, error) {
|
func (s *Service) AttestationTargetState(ctx context.Context, target *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
ss, err := slots.EpochStart(target.Epoch)
|
ss, err := slots.EpochStart(target.Epoch)
|
||||||
@@ -83,7 +66,8 @@ func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestat
|
|||||||
func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) error {
|
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.
|
// 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.
|
// In this case, we could exit early to save on additional computation.
|
||||||
if s.cfg.ForkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
|
blockRoot := bytesutil.ToBytes32(root)
|
||||||
|
if s.cfg.ForkChoiceStore.HasNode(blockRoot) && s.cfg.ForkChoiceStore.IsCanonical(blockRoot) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,46 +128,66 @@ func (s *Service) spawnProcessAttestationsRoutine(stateFeed *event.Feed) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue when there's no fork choice attestation, there's nothing to process and update head.
|
if err := s.UpdateHead(s.ctx); err != nil {
|
||||||
// This covers the condition when the node is still initial syncing to the head of the chain.
|
log.WithError(err).Error("Could not process attestations and update head")
|
||||||
if s.cfg.AttPool.ForkchoiceAttestationCount() == 0 {
|
return
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
s.processAttestations(s.ctx)
|
|
||||||
|
|
||||||
justified := s.store.JustifiedCheckpt()
|
|
||||||
if justified == nil {
|
|
||||||
log.WithError(errNilJustifiedInStore).Error("Could not get justified checkpoint")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
balances, err := s.justifiedBalances.get(s.ctx, bytesutil.ToBytes32(justified.Root))
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Errorf("Unable to get justified balances for root %v", justified.Root)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newHeadRoot, err := s.updateHead(s.ctx, balances)
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Warn("Resolving fork due to new attestation")
|
|
||||||
}
|
|
||||||
s.notifyEngineIfChangedHead(s.ctx, newHeadRoot)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateHead updates the canonical head of the chain based on information from fork-choice attestations and votes.
|
||||||
|
// It requires no external inputs.
|
||||||
|
func (s *Service) UpdateHead(ctx context.Context) error {
|
||||||
|
// 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 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one process can process attestations and update head at a time.
|
||||||
|
s.processAttestationsLock.Lock()
|
||||||
|
defer s.processAttestationsLock.Unlock()
|
||||||
|
|
||||||
|
s.processAttestations(ctx)
|
||||||
|
|
||||||
|
justified := s.store.JustifiedCheckpt()
|
||||||
|
if justified == nil {
|
||||||
|
return errNilJustifiedInStore
|
||||||
|
}
|
||||||
|
balances, err := s.justifiedBalances.get(ctx, bytesutil.ToBytes32(justified.Root))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newHeadRoot, err := s.updateHead(ctx, balances)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Warn("Resolving fork due to new attestation")
|
||||||
|
}
|
||||||
|
if s.headRoot() != newHeadRoot {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"oldHeadRoot": fmt.Sprintf("%#x", s.headRoot()),
|
||||||
|
"newHeadRoot": fmt.Sprintf("%#x", newHeadRoot),
|
||||||
|
}).Debug("Head changed due to attestations")
|
||||||
|
}
|
||||||
|
s.notifyEngineIfChangedHead(ctx, newHeadRoot)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// This calls notify Forkchoice Update in the event that the head has changed
|
// This calls notify Forkchoice Update in the event that the head has changed
|
||||||
func (s *Service) notifyEngineIfChangedHead(ctx context.Context, newHeadRoot [32]byte) {
|
func (s *Service) notifyEngineIfChangedHead(ctx context.Context, newHeadRoot [32]byte) {
|
||||||
if s.headRoot() == newHeadRoot {
|
if s.headRoot() == newHeadRoot {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
finalized := s.store.FinalizedCheckpt()
|
|
||||||
if finalized == nil {
|
if !s.hasBlockInInitSyncOrDB(ctx, newHeadRoot) {
|
||||||
log.WithError(errNilFinalizedInStore).Error("could not get finalized checkpoint")
|
log.Debug("New head does not exist in DB. Do nothing")
|
||||||
return
|
return // We don't have the block, don't notify the engine and update head.
|
||||||
}
|
}
|
||||||
newHeadBlock, err := s.cfg.BeaconDB.Block(ctx, newHeadRoot)
|
|
||||||
|
newHeadBlock, err := s.getBlock(ctx, newHeadRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("Could not get block from db")
|
log.WithError(err).Error("Could not get new head block")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
headState, err := s.cfg.StateGen.StateByRoot(ctx, newHeadRoot)
|
headState, err := s.cfg.StateGen.StateByRoot(ctx, newHeadRoot)
|
||||||
@@ -191,12 +195,12 @@ func (s *Service) notifyEngineIfChangedHead(ctx context.Context, newHeadRoot [32
|
|||||||
log.WithError(err).Error("Could not get state from db")
|
log.WithError(err).Error("Could not get state from db")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = s.notifyForkchoiceUpdate(s.ctx,
|
arg := ¬ifyForkchoiceUpdateArg{
|
||||||
headState,
|
headState: headState,
|
||||||
newHeadBlock.Block(),
|
headRoot: newHeadRoot,
|
||||||
newHeadRoot,
|
headBlock: newHeadBlock.Block(),
|
||||||
bytesutil.ToBytes32(finalized.Root),
|
}
|
||||||
)
|
_, err = s.notifyForkchoiceUpdate(s.ctx, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("could not notify forkchoice update")
|
log.WithError(err).Error("could not notify forkchoice update")
|
||||||
}
|
}
|
||||||
@@ -231,7 +235,7 @@ func (s *Service) processAttestations(ctx context.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.ReceiveAttestationNoPubsub(ctx, a); err != nil {
|
if err := s.receiveAttestationNoPubsub(ctx, a); err != nil {
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"slot": a.Data.Slot,
|
"slot": a.Data.Slot,
|
||||||
"committeeIndex": a.Data.CommitteeIndex,
|
"committeeIndex": a.Data.CommitteeIndex,
|
||||||
@@ -242,3 +246,19 @@ func (s *Service) processAttestations(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// receiveAttestationNoPubsub is a function that defines the operations that are performed on
|
||||||
|
// attestation that is received from regular sync. The operations consist of:
|
||||||
|
// 1. Validate attestation, update validator's latest vote
|
||||||
|
// 2. Apply fork choice to the processed attestation
|
||||||
|
// 3. Save latest head info
|
||||||
|
func (s *Service) receiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation) error {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.receiveAttestationNoPubsub")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if err := s.OnAttestation(ctx, att); err != nil {
|
||||||
|
return errors.Wrap(err, "could not process attestation")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
prysmTime "github.com/prysmaticlabs/prysm/time"
|
prysmTime "github.com/prysmaticlabs/prysm/time"
|
||||||
@@ -137,11 +137,14 @@ func TestNotifyEngineIfChangedHead(t *testing.T) {
|
|||||||
service.cfg.ProposerSlotIndexCache = cache.NewProposerPayloadIDsCache()
|
service.cfg.ProposerSlotIndexCache = cache.NewProposerPayloadIDsCache()
|
||||||
service.notifyEngineIfChangedHead(ctx, service.headRoot())
|
service.notifyEngineIfChangedHead(ctx, service.headRoot())
|
||||||
hookErr := "could not notify forkchoice update"
|
hookErr := "could not notify forkchoice update"
|
||||||
finalizedErr := "could not get finalized checkpoint"
|
invalidStateErr := "Could not get state from db"
|
||||||
require.LogsDoNotContain(t, hook, finalizedErr)
|
require.LogsDoNotContain(t, hook, invalidStateErr)
|
||||||
require.LogsDoNotContain(t, hook, hookErr)
|
require.LogsDoNotContain(t, hook, hookErr)
|
||||||
|
gb, err := wrapper.WrappedSignedBeaconBlock(util.NewBeaconBlock())
|
||||||
|
require.NoError(t, err)
|
||||||
|
service.saveInitSyncBlock([32]byte{'a'}, gb)
|
||||||
service.notifyEngineIfChangedHead(ctx, [32]byte{'a'})
|
service.notifyEngineIfChangedHead(ctx, [32]byte{'a'})
|
||||||
require.LogsContain(t, hook, finalizedErr)
|
require.LogsContain(t, hook, invalidStateErr)
|
||||||
|
|
||||||
hook.Reset()
|
hook.Reset()
|
||||||
service.head = &head{
|
service.head = &head{
|
||||||
@@ -149,13 +152,14 @@ func TestNotifyEngineIfChangedHead(t *testing.T) {
|
|||||||
block: nil, /* should not panic if notify head uses correct head */
|
block: nil, /* should not panic if notify head uses correct head */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Block in Cache
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
b.Block.Slot = 2
|
b.Block.Slot = 2
|
||||||
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb))
|
|
||||||
r1, err := b.Block.HashTreeRoot()
|
r1, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
service.saveInitSyncBlock(r1, wsb)
|
||||||
finalized := ðpb.Checkpoint{Root: r1[:], Epoch: 0}
|
finalized := ðpb.Checkpoint{Root: r1[:], Epoch: 0}
|
||||||
st, _ := util.DeterministicGenesisState(t, 1)
|
st, _ := util.DeterministicGenesisState(t, 1)
|
||||||
service.head = &head{
|
service.head = &head{
|
||||||
@@ -165,12 +169,68 @@ func TestNotifyEngineIfChangedHead(t *testing.T) {
|
|||||||
state: st,
|
state: st,
|
||||||
}
|
}
|
||||||
service.cfg.ProposerSlotIndexCache.SetProposerAndPayloadIDs(2, 1, [8]byte{1})
|
service.cfg.ProposerSlotIndexCache.SetProposerAndPayloadIDs(2, 1, [8]byte{1})
|
||||||
service.store.SetFinalizedCheckpt(finalized)
|
service.store.SetFinalizedCheckptAndPayloadHash(finalized, [32]byte{})
|
||||||
service.notifyEngineIfChangedHead(ctx, r1)
|
service.notifyEngineIfChangedHead(ctx, r1)
|
||||||
require.LogsDoNotContain(t, hook, finalizedErr)
|
require.LogsDoNotContain(t, hook, invalidStateErr)
|
||||||
|
require.LogsDoNotContain(t, hook, hookErr)
|
||||||
|
|
||||||
|
// Block in DB
|
||||||
|
b = util.NewBeaconBlock()
|
||||||
|
b.Block.Slot = 3
|
||||||
|
wsb, err = wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb))
|
||||||
|
r1, err = b.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
finalized = ðpb.Checkpoint{Root: r1[:], Epoch: 0}
|
||||||
|
st, _ = util.DeterministicGenesisState(t, 1)
|
||||||
|
service.head = &head{
|
||||||
|
slot: 1,
|
||||||
|
root: r1,
|
||||||
|
block: wsb,
|
||||||
|
state: st,
|
||||||
|
}
|
||||||
|
service.cfg.ProposerSlotIndexCache.SetProposerAndPayloadIDs(2, 1, [8]byte{1})
|
||||||
|
service.store.SetFinalizedCheckptAndPayloadHash(finalized, [32]byte{})
|
||||||
|
service.notifyEngineIfChangedHead(ctx, r1)
|
||||||
|
require.LogsDoNotContain(t, hook, invalidStateErr)
|
||||||
require.LogsDoNotContain(t, hook, hookErr)
|
require.LogsDoNotContain(t, hook, hookErr)
|
||||||
vId, payloadID, has := service.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(2)
|
vId, payloadID, has := service.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(2)
|
||||||
require.Equal(t, true, has)
|
require.Equal(t, true, has)
|
||||||
require.Equal(t, types.ValidatorIndex(1), vId)
|
require.Equal(t, types.ValidatorIndex(1), vId)
|
||||||
require.Equal(t, [8]byte{1}, payloadID)
|
require.Equal(t, [8]byte{1}, payloadID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
opts := testServiceOptsWithDB(t)
|
||||||
|
opts = append(opts, WithAttestationPool(attestations.NewPool()), WithStateNotifier(&mockBeaconNode{}))
|
||||||
|
|
||||||
|
service, err := NewService(ctx, opts...)
|
||||||
|
require.NoError(t, err)
|
||||||
|
service.genesisTime = prysmTime.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||||
|
genesisState, pks := util.DeterministicGenesisState(t, 64)
|
||||||
|
require.NoError(t, genesisState.SetGenesisTime(uint64(prysmTime.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
|
||||||
|
require.NoError(t, service.saveGenesisData(ctx, genesisState))
|
||||||
|
atts, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root)
|
||||||
|
copied := genesisState.Copy()
|
||||||
|
copied, err = transition.ProcessSlots(ctx, copied, 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{Root: tRoot[:]}))
|
||||||
|
require.NoError(t, service.cfg.ForkChoiceStore.InsertOptimisticBlock(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, 1, 1))
|
||||||
|
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(atts))
|
||||||
|
b := util.NewBeaconBlock()
|
||||||
|
wb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r, err := b.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wb))
|
||||||
|
service.head.root = r // Old head
|
||||||
|
require.Equal(t, 1, len(service.cfg.AttPool.ForkchoiceAttestations()))
|
||||||
|
require.NoError(t, err, service.UpdateHead(ctx))
|
||||||
|
require.Equal(t, tRoot, service.head.root) // Validate head is the new one
|
||||||
|
require.Equal(t, 0, len(service.cfg.AttPool.ForkchoiceAttestations())) // Validate att pool is empty
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time"
|
"github.com/prysmaticlabs/prysm/time"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@@ -17,19 +18,24 @@ import (
|
|||||||
// This defines how many epochs since finality the run time will begin to save hot state on to the DB.
|
// This defines how many epochs since finality the run time will begin to save hot state on to the DB.
|
||||||
var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
|
var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
|
||||||
|
|
||||||
// BlockReceiver interface defines the methods of chain service receive and processing new blocks.
|
// BlockReceiver interface defines the methods of chain service for receiving and processing new blocks.
|
||||||
type BlockReceiver interface {
|
type BlockReceiver interface {
|
||||||
ReceiveBlock(ctx context.Context, block block.SignedBeaconBlock, blockRoot [32]byte) error
|
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
|
||||||
ReceiveBlockBatch(ctx context.Context, blocks []block.SignedBeaconBlock, blkRoots [][32]byte) error
|
ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error
|
||||||
HasInitSyncBlock(root [32]byte) bool
|
HasBlock(ctx context.Context, root [32]byte) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveBlock is a function that defines the the operations (minus pubsub)
|
// SlashingReceiver interface defines the methods of chain service for receiving validated slashing over the wire.
|
||||||
// that are performed on blocks that is received from regular sync service. The operations consists of:
|
type SlashingReceiver interface {
|
||||||
// 1. Validate block, apply state transition and update check points
|
ReceiveAttesterSlashing(ctx context.Context, slashings *ethpb.AttesterSlashing)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveBlock is a function that defines the operations (minus pubsub)
|
||||||
|
// that are performed on a received block. The operations consist of:
|
||||||
|
// 1. Validate block, apply state transition and update checkpoints
|
||||||
// 2. Apply fork choice to the processed block
|
// 2. Apply fork choice to the processed block
|
||||||
// 3. Save latest head info
|
// 3. Save latest head info
|
||||||
func (s *Service) ReceiveBlock(ctx context.Context, block block.SignedBeaconBlock, blockRoot [32]byte) error {
|
func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
|
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
receivedTime := time.Now()
|
receivedTime := time.Now()
|
||||||
@@ -74,12 +80,12 @@ func (s *Service) ReceiveBlock(ctx context.Context, block block.SignedBeaconBloc
|
|||||||
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
|
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
|
||||||
// the state, performing batch verification of all collected signatures and then performing the appropriate
|
// the state, performing batch verification of all collected signatures and then performing the appropriate
|
||||||
// actions for a block post-transition.
|
// actions for a block post-transition.
|
||||||
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []block.SignedBeaconBlock, blkRoots [][32]byte) error {
|
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
|
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// Apply state transition on the incoming newly received blockCopy without verifying its BLS contents.
|
// Apply state transition on the incoming newly received block batches, one by one.
|
||||||
fCheckpoints, jCheckpoints, err := s.onBlockBatch(ctx, blocks, blkRoots)
|
_, _, err := s.onBlockBatch(ctx, blocks, blkRoots)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := errors.Wrap(err, "could not process block in batch")
|
err := errors.Wrap(err, "could not process block in batch")
|
||||||
tracing.AnnotateError(span, err)
|
tracing.AnnotateError(span, err)
|
||||||
@@ -88,10 +94,6 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []block.SignedBe
|
|||||||
|
|
||||||
for i, b := range blocks {
|
for i, b := range blocks {
|
||||||
blockCopy := b.Copy()
|
blockCopy := b.Copy()
|
||||||
if err = s.handleBlockAfterBatchVerify(ctx, blockCopy, blkRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
|
|
||||||
tracing.AnnotateError(span, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Send notification of the processed block to the state feed.
|
// Send notification of the processed block to the state feed.
|
||||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||||
Type: statefeed.BlockProcessed,
|
Type: statefeed.BlockProcessed,
|
||||||
@@ -128,12 +130,17 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []block.SignedBe
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasInitSyncBlock returns true if the block of the input root exists in initial sync blocks cache.
|
// HasBlock returns true if the block of the input root exists in initial sync blocks cache or DB.
|
||||||
func (s *Service) HasInitSyncBlock(root [32]byte) bool {
|
func (s *Service) HasBlock(ctx context.Context, root [32]byte) bool {
|
||||||
return s.hasInitSyncBlock(root)
|
return s.hasBlockInInitSyncOrDB(ctx, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) handlePostBlockOperations(b block.BeaconBlock) error {
|
// ReceiveAttesterSlashing receives an attester slashing and inserts it to forkchoice
|
||||||
|
func (s *Service) ReceiveAttesterSlashing(ctx context.Context, slashing *ethpb.AttesterSlashing) {
|
||||||
|
s.insertSlashingsToForkChoiceStore(ctx, []*ethpb.AttesterSlashing{slashing})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) handlePostBlockOperations(b interfaces.BeaconBlock) error {
|
||||||
// Delete the processed block attestations from attestation pool.
|
// Delete the processed block attestations from attestation pool.
|
||||||
if err := s.deletePoolAtts(b.Body().Attestations()); err != nil {
|
if err := s.deletePoolAtts(b.Body().Attestations()); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||||
@@ -14,10 +13,11 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
|
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -141,7 +141,8 @@ func TestService_ReceiveBlock(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
h := [32]byte{'a'}
|
||||||
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, h)
|
||||||
root, err := tt.args.block.Block.HashTreeRoot()
|
root, err := tt.args.block.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
wsb, err := wrapper.WrappedSignedBeaconBlock(tt.args.block)
|
wsb, err := wrapper.WrappedSignedBeaconBlock(tt.args.block)
|
||||||
@@ -181,7 +182,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
root, err := b.Block.HashTreeRoot()
|
root, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
@@ -262,12 +263,12 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
|
|||||||
|
|
||||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Root: gRoot[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: gRoot[:]}, [32]byte{'a'})
|
||||||
root, err := tt.args.block.Block.HashTreeRoot()
|
root, err := tt.args.block.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
wsb, err := wrapper.WrappedSignedBeaconBlock(tt.args.block)
|
wsb, err := wrapper.WrappedSignedBeaconBlock(tt.args.block)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
blks := []block.SignedBeaconBlock{wsb}
|
blks := []interfaces.SignedBeaconBlock{wsb}
|
||||||
roots := [][32]byte{root}
|
roots := [][32]byte{root}
|
||||||
err = s.ReceiveBlockBatch(ctx, blks, roots)
|
err = s.ReceiveBlockBatch(ctx, blks, roots)
|
||||||
if tt.wantedErr != "" {
|
if tt.wantedErr != "" {
|
||||||
@@ -280,21 +281,29 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_HasInitSyncBlock(t *testing.T) {
|
func TestService_HasBlock(t *testing.T) {
|
||||||
opts := testServiceOptsNoDB()
|
opts := testServiceOptsWithDB(t)
|
||||||
opts = append(opts, WithStateNotifier(&blockchainTesting.MockStateNotifier{}))
|
opts = append(opts, WithStateNotifier(&blockchainTesting.MockStateNotifier{}))
|
||||||
s, err := NewService(context.Background(), opts...)
|
s, err := NewService(context.Background(), opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r := [32]byte{'a'}
|
r := [32]byte{'a'}
|
||||||
if s.HasInitSyncBlock(r) {
|
if s.HasBlock(context.Background(), r) {
|
||||||
t.Error("Should not have block")
|
t.Error("Should not have block")
|
||||||
}
|
}
|
||||||
wsb, err := wrapper.WrappedSignedBeaconBlock(util.NewBeaconBlock())
|
wsb, err := wrapper.WrappedSignedBeaconBlock(util.NewBeaconBlock())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.saveInitSyncBlock(r, wsb)
|
s.saveInitSyncBlock(r, wsb)
|
||||||
if !s.HasInitSyncBlock(r) {
|
if !s.HasBlock(context.Background(), r) {
|
||||||
t.Error("Should have block")
|
t.Error("Should have block")
|
||||||
}
|
}
|
||||||
|
b := util.NewBeaconBlock()
|
||||||
|
b.Block.Slot = 1
|
||||||
|
wsb, err = wrapper.WrappedSignedBeaconBlock(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
r, err = b.Block.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, s.cfg.BeaconDB.SaveBlock(context.Background(), wsb))
|
||||||
|
require.Equal(t, true, s.HasBlock(context.Background(), r))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
|
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
|
||||||
@@ -304,7 +313,7 @@ func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
st := params.BeaconConfig().SlotsPerEpoch.Mul(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.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{}, [32]byte{})
|
||||||
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
||||||
assert.LogsContain(t, hook, "Entering mode to save hot states in DB")
|
assert.LogsContain(t, hook, "Entering mode to save hot states in DB")
|
||||||
@@ -315,7 +324,7 @@ func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
|
|||||||
opts := testServiceOptsWithDB(t)
|
opts := testServiceOptsWithDB(t)
|
||||||
s, err := NewService(context.Background(), opts...)
|
s, err := NewService(context.Background(), opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{}, [32]byte{})
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
||||||
s.genesisTime = time.Now()
|
s.genesisTime = time.Now()
|
||||||
|
|
||||||
@@ -328,7 +337,7 @@ func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
|
|||||||
opts := testServiceOptsWithDB(t)
|
opts := testServiceOptsWithDB(t)
|
||||||
s, err := NewService(context.Background(), opts...)
|
s, err := NewService(context.Background(), opts...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 10000000})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{}, [32]byte{})
|
||||||
s.genesisTime = time.Now()
|
s.genesisTime = time.Now()
|
||||||
|
|
||||||
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/async/event"
|
"github.com/prysmaticlabs/prysm/async/event"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
@@ -34,9 +33,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
prysmTime "github.com/prysmaticlabs/prysm/time"
|
prysmTime "github.com/prysmaticlabs/prysm/time"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -50,22 +50,22 @@ const headSyncMinEpochsAfterCheckpoint = 128
|
|||||||
// Service represents a service that handles the internal
|
// Service represents a service that handles the internal
|
||||||
// logic of managing the full PoS beacon chain.
|
// logic of managing the full PoS beacon chain.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
cfg *config
|
cfg *config
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
genesisTime time.Time
|
genesisTime time.Time
|
||||||
head *head
|
head *head
|
||||||
headLock sync.RWMutex
|
headLock sync.RWMutex
|
||||||
// originBlockRoot is the genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
originBlockRoot [32]byte // genesis root, or weak subjectivity checkpoint root, depending on how the node is initialized
|
||||||
originBlockRoot [32]byte
|
nextEpochBoundarySlot types.Slot
|
||||||
nextEpochBoundarySlot types.Slot
|
boundaryRoots [][32]byte
|
||||||
boundaryRoots [][32]byte
|
checkpointStateCache *cache.CheckpointStateCache
|
||||||
checkpointStateCache *cache.CheckpointStateCache
|
initSyncBlocks map[[32]byte]interfaces.SignedBeaconBlock
|
||||||
initSyncBlocks map[[32]byte]block.SignedBeaconBlock
|
initSyncBlocksLock sync.RWMutex
|
||||||
initSyncBlocksLock sync.RWMutex
|
justifiedBalances *stateBalanceCache
|
||||||
justifiedBalances *stateBalanceCache
|
wsVerifier *WeakSubjectivityVerifier
|
||||||
wsVerifier *WeakSubjectivityVerifier
|
store *store.Store
|
||||||
store *store.Store
|
processAttestationsLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// config options for the service.
|
// config options for the service.
|
||||||
@@ -100,7 +100,7 @@ func NewService(ctx context.Context, opts ...Option) (*Service, error) {
|
|||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
boundaryRoots: [][32]byte{},
|
boundaryRoots: [][32]byte{},
|
||||||
checkpointStateCache: cache.NewCheckpointStateCache(),
|
checkpointStateCache: cache.NewCheckpointStateCache(),
|
||||||
initSyncBlocks: make(map[[32]byte]block.SignedBeaconBlock),
|
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
|
||||||
cfg: &config{},
|
cfg: &config{},
|
||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
}
|
}
|
||||||
@@ -144,6 +144,7 @@ func (s *Service) Stop() error {
|
|||||||
defer s.cancel()
|
defer s.cancel()
|
||||||
|
|
||||||
if s.cfg.StateGen != nil && s.head != nil && s.head.state != nil {
|
if s.cfg.StateGen != nil && s.head != nil && s.head.state != nil {
|
||||||
|
// Save the last finalized state so that starting up in the following run will be much faster.
|
||||||
if err := s.cfg.StateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
|
if err := s.cfg.StateGen.ForceCheckpoint(s.ctx, s.head.state.FinalizedCheckpoint().Root); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -160,11 +161,12 @@ func (s *Service) Status() error {
|
|||||||
return errors.New("genesis state has not been created")
|
return errors.New("genesis state has not been created")
|
||||||
}
|
}
|
||||||
if runtime.NumGoroutine() > s.cfg.MaxRoutines {
|
if runtime.NumGoroutine() > s.cfg.MaxRoutines {
|
||||||
return fmt.Errorf("too many goroutines %d", runtime.NumGoroutine())
|
return fmt.Errorf("too many goroutines (%d)", runtime.NumGoroutine())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartFromSavedState initializes the blockchain using a previously saved finalized checkpoint.
|
||||||
func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
||||||
log.Info("Blockchain data already exists in DB, initializing...")
|
log.Info("Blockchain data already exists in DB, initializing...")
|
||||||
s.genesisTime = time.Unix(int64(saved.GenesisTime()), 0) // lint:ignore uintcast -- Genesis time will not exceed int64 in your lifetime.
|
s.genesisTime = time.Unix(int64(saved.GenesisTime()), 0) // lint:ignore uintcast -- Genesis time will not exceed int64 in your lifetime.
|
||||||
@@ -191,19 +193,19 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
}
|
}
|
||||||
s.store = store.New(justified, finalized)
|
s.store = store.New(justified, finalized)
|
||||||
|
|
||||||
var f f.ForkChoicer
|
var forkChoicer f.ForkChoicer
|
||||||
fRoot := bytesutil.ToBytes32(finalized.Root)
|
fRoot := bytesutil.ToBytes32(finalized.Root)
|
||||||
if features.Get().EnableForkChoiceDoublyLinkedTree {
|
if features.Get().EnableForkChoiceDoublyLinkedTree {
|
||||||
f = doublylinkedtree.New(justified.Epoch, finalized.Epoch)
|
forkChoicer = doublylinkedtree.New(justified.Epoch, finalized.Epoch)
|
||||||
} else {
|
} else {
|
||||||
f = protoarray.New(justified.Epoch, finalized.Epoch, fRoot)
|
forkChoicer = protoarray.New(justified.Epoch, finalized.Epoch, fRoot)
|
||||||
}
|
}
|
||||||
s.cfg.ForkChoiceStore = f
|
s.cfg.ForkChoiceStore = forkChoicer
|
||||||
fb, err := s.cfg.BeaconDB.Block(s.ctx, s.ensureRootNotZeros(fRoot))
|
fb, err := s.cfg.BeaconDB.Block(s.ctx, s.ensureRootNotZeros(fRoot))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not get finalized checkpoint block")
|
return errors.Wrap(err, "could not get finalized checkpoint block")
|
||||||
}
|
}
|
||||||
if fb == nil {
|
if fb == nil || fb.IsNil() {
|
||||||
return errNilFinalizedInStore
|
return errNilFinalizedInStore
|
||||||
}
|
}
|
||||||
payloadHash, err := getBlockPayloadHash(fb.Block())
|
payloadHash, err := getBlockPayloadHash(fb.Block())
|
||||||
@@ -211,7 +213,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
return errors.Wrap(err, "could not get execution payload hash")
|
return errors.Wrap(err, "could not get execution payload hash")
|
||||||
}
|
}
|
||||||
fSlot := fb.Block().Slot()
|
fSlot := fb.Block().Slot()
|
||||||
if err := f.InsertOptimisticBlock(s.ctx, fSlot, fRoot, params.BeaconConfig().ZeroHash,
|
if err := forkChoicer.InsertOptimisticBlock(s.ctx, fSlot, fRoot, params.BeaconConfig().ZeroHash,
|
||||||
payloadHash, justified.Epoch, finalized.Epoch); err != nil {
|
payloadHash, justified.Epoch, finalized.Epoch); err != nil {
|
||||||
return errors.Wrap(err, "could not insert finalized block to forkchoice")
|
return errors.Wrap(err, "could not insert finalized block to forkchoice")
|
||||||
}
|
}
|
||||||
@@ -221,7 +223,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
|||||||
return errors.Wrap(err, "could not get last validated checkpoint")
|
return errors.Wrap(err, "could not get last validated checkpoint")
|
||||||
}
|
}
|
||||||
if bytes.Equal(finalized.Root, lastValidatedCheckpoint.Root) {
|
if bytes.Equal(finalized.Root, lastValidatedCheckpoint.Root) {
|
||||||
if err := f.SetOptimisticToValid(s.ctx, fRoot); err != nil {
|
if err := forkChoicer.SetOptimisticToValid(s.ctx, fRoot); err != nil {
|
||||||
return errors.Wrap(err, "could not set finalized block as validated")
|
return errors.Wrap(err, "could not set finalized block as validated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,9 +283,9 @@ func (s *Service) originRootFromSavedState(ctx context.Context) ([32]byte, error
|
|||||||
return genesisBlkRoot, nil
|
return genesisBlkRoot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializeHeadFromDB uses the finalized checkpoint and head block found in the database to set the current head
|
// initializeHeadFromDB uses the finalized checkpoint and head block found in the database to set the current head.
|
||||||
// note that this may block until stategen replays blocks between the finalized and head blocks
|
// Note that this may block until stategen replays blocks between the finalized and head blocks
|
||||||
// if the head sync flag was specified and the gap between the finalized and head blocks is at least 128 epochs long
|
// if the head sync flag was specified and the gap between the finalized and head blocks is at least 128 epochs long.
|
||||||
func (s *Service) initializeHeadFromDB(ctx context.Context) error {
|
func (s *Service) initializeHeadFromDB(ctx context.Context) error {
|
||||||
finalized, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
|
finalized, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package blockchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logrus.SetLevel(logrus.DebugLevel)
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
logrus.SetOutput(ioutil.Discard)
|
logrus.SetOutput(io.Discard)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChainService_SaveHead_DataRace(t *testing.T) {
|
func TestChainService_SaveHead_DataRace(t *testing.T) {
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ import (
|
|||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -221,7 +221,8 @@ func TestChainService_InitializeBeaconChain(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
trie, _, err := util.DepositTrieFromDeposits(deposits)
|
trie, _, err := util.DepositTrieFromDeposits(deposits)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
hashTreeRoot := trie.HashTreeRoot()
|
hashTreeRoot, err := trie.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
genState, err := transition.EmptyGenesisState()
|
genState, err := transition.EmptyGenesisState()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = genState.SetEth1Data(ðpb.Eth1Data{
|
err = genState.SetEth1Data(ðpb.Eth1Data{
|
||||||
@@ -500,7 +501,7 @@ func TestHasBlock_ForkChoiceAndDB_ProtoArray(t *testing.T) {
|
|||||||
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
|
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
|
||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
}
|
}
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]}, [32]byte{})
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
r, err := b.Block.HashTreeRoot()
|
r, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -521,7 +522,7 @@ func TestHasBlock_ForkChoiceAndDB_DoublyLinkedTree(t *testing.T) {
|
|||||||
cfg: &config{ForkChoiceStore: doublylinkedtree.New(0, 0), BeaconDB: beaconDB},
|
cfg: &config{ForkChoiceStore: doublylinkedtree.New(0, 0), BeaconDB: beaconDB},
|
||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
}
|
}
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]}, [32]byte{})
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
r, err := b.Block.HashTreeRoot()
|
r, err := b.Block.HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -542,7 +543,7 @@ func TestServiceStop_SaveCachedBlocks(t *testing.T) {
|
|||||||
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
|
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
initSyncBlocks: make(map[[32]byte]block.SignedBeaconBlock),
|
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
|
||||||
}
|
}
|
||||||
b := util.NewBeaconBlock()
|
b := util.NewBeaconBlock()
|
||||||
r, err := b.Block.HashTreeRoot()
|
r, err := b.Block.HashTreeRoot()
|
||||||
@@ -594,7 +595,7 @@ func BenchmarkHasBlockForkChoiceStore_ProtoArray(b *testing.B) {
|
|||||||
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
|
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
|
||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
}
|
}
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]}, [32]byte{})
|
||||||
blk := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}
|
blk := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}
|
||||||
r, err := blk.Block.HashTreeRoot()
|
r, err := blk.Block.HashTreeRoot()
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
@@ -617,7 +618,7 @@ func BenchmarkHasBlockForkChoiceStore_DoublyLinkedTree(b *testing.B) {
|
|||||||
cfg: &config{ForkChoiceStore: doublylinkedtree.New(0, 0), BeaconDB: beaconDB},
|
cfg: &config{ForkChoiceStore: doublylinkedtree.New(0, 0), BeaconDB: beaconDB},
|
||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
}
|
}
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: 0, Root: params.BeaconConfig().ZeroHash[:]}, [32]byte{})
|
||||||
blk := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}
|
blk := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Body: ðpb.BeaconBlockBody{}}}
|
||||||
r, err := blk.Block.HashTreeRoot()
|
r, err := blk.Block.HashTreeRoot()
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// New creates a store object.
|
||||||
func New(justifiedCheckpt *ethpb.Checkpoint, finalizedCheckpt *ethpb.Checkpoint) *Store {
|
func New(justifiedCheckpt *ethpb.Checkpoint, finalizedCheckpt *ethpb.Checkpoint) *Store {
|
||||||
return &Store{
|
return &Store{
|
||||||
justifiedCheckpt: justifiedCheckpt,
|
justifiedCheckpt: justifiedCheckpt,
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ func (s *Store) JustifiedCheckpt() *ethpb.Checkpoint {
|
|||||||
return s.justifiedCheckpt
|
return s.justifiedCheckpt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JustifiedPayloadBlockHash returns the justified payload block hash reflecting justified check point.
|
||||||
|
func (s *Store) JustifiedPayloadBlockHash() [32]byte {
|
||||||
|
s.RLock()
|
||||||
|
defer s.RUnlock()
|
||||||
|
return s.justifiedPayloadBlockHash
|
||||||
|
}
|
||||||
|
|
||||||
// PrevFinalizedCheckpt returns the previous finalized checkpoint in the Store.
|
// PrevFinalizedCheckpt returns the previous finalized checkpoint in the Store.
|
||||||
func (s *Store) PrevFinalizedCheckpt() *ethpb.Checkpoint {
|
func (s *Store) PrevFinalizedCheckpt() *ethpb.Checkpoint {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
@@ -37,6 +44,13 @@ func (s *Store) FinalizedCheckpt() *ethpb.Checkpoint {
|
|||||||
return s.finalizedCheckpt
|
return s.finalizedCheckpt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FinalizedPayloadBlockHash returns the finalized payload block hash reflecting finalized check point.
|
||||||
|
func (s *Store) FinalizedPayloadBlockHash() [32]byte {
|
||||||
|
s.RLock()
|
||||||
|
defer s.RUnlock()
|
||||||
|
return s.finalizedPayloadBlockHash
|
||||||
|
}
|
||||||
|
|
||||||
// SetPrevJustifiedCheckpt sets the previous justified checkpoint in the Store.
|
// SetPrevJustifiedCheckpt sets the previous justified checkpoint in the Store.
|
||||||
func (s *Store) SetPrevJustifiedCheckpt(cp *ethpb.Checkpoint) {
|
func (s *Store) SetPrevJustifiedCheckpt(cp *ethpb.Checkpoint) {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
@@ -51,18 +65,20 @@ func (s *Store) SetBestJustifiedCheckpt(cp *ethpb.Checkpoint) {
|
|||||||
s.bestJustifiedCheckpt = cp
|
s.bestJustifiedCheckpt = cp
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetJustifiedCheckpt sets the justified checkpoint in the Store.
|
// SetJustifiedCheckptAndPayloadHash sets the justified checkpoint and blockhash in the Store.
|
||||||
func (s *Store) SetJustifiedCheckpt(cp *ethpb.Checkpoint) {
|
func (s *Store) SetJustifiedCheckptAndPayloadHash(cp *ethpb.Checkpoint, h [32]byte) {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
defer s.Unlock()
|
defer s.Unlock()
|
||||||
s.justifiedCheckpt = cp
|
s.justifiedCheckpt = cp
|
||||||
|
s.justifiedPayloadBlockHash = h
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFinalizedCheckpt sets the finalized checkpoint in the Store.
|
// SetFinalizedCheckptAndPayloadHash sets the finalized checkpoint and blockhash in the Store.
|
||||||
func (s *Store) SetFinalizedCheckpt(cp *ethpb.Checkpoint) {
|
func (s *Store) SetFinalizedCheckptAndPayloadHash(cp *ethpb.Checkpoint, h [32]byte) {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
defer s.Unlock()
|
defer s.Unlock()
|
||||||
s.finalizedCheckpt = cp
|
s.finalizedCheckpt = cp
|
||||||
|
s.finalizedPayloadBlockHash = h
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPrevFinalizedCheckpt sets the previous finalized checkpoint in the Store.
|
// SetPrevFinalizedCheckpt sets the previous finalized checkpoint in the Store.
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ func Test_store_JustifiedCheckpt(t *testing.T) {
|
|||||||
var cp *ethpb.Checkpoint
|
var cp *ethpb.Checkpoint
|
||||||
require.Equal(t, cp, s.JustifiedCheckpt())
|
require.Equal(t, cp, s.JustifiedCheckpt())
|
||||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||||
s.SetJustifiedCheckpt(cp)
|
h := [32]byte{'b'}
|
||||||
|
s.SetJustifiedCheckptAndPayloadHash(cp, h)
|
||||||
require.Equal(t, cp, s.JustifiedCheckpt())
|
require.Equal(t, cp, s.JustifiedCheckpt())
|
||||||
|
require.Equal(t, h, s.JustifiedPayloadBlockHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_store_FinalizedCheckpt(t *testing.T) {
|
func Test_store_FinalizedCheckpt(t *testing.T) {
|
||||||
@@ -39,8 +41,10 @@ func Test_store_FinalizedCheckpt(t *testing.T) {
|
|||||||
var cp *ethpb.Checkpoint
|
var cp *ethpb.Checkpoint
|
||||||
require.Equal(t, cp, s.FinalizedCheckpt())
|
require.Equal(t, cp, s.FinalizedCheckpt())
|
||||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||||
s.SetFinalizedCheckpt(cp)
|
h := [32]byte{'b'}
|
||||||
|
s.SetFinalizedCheckptAndPayloadHash(cp, h)
|
||||||
require.Equal(t, cp, s.FinalizedCheckpt())
|
require.Equal(t, cp, s.FinalizedCheckpt())
|
||||||
|
require.Equal(t, h, s.FinalizedPayloadBlockHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_store_PrevFinalizedCheckpt(t *testing.T) {
|
func Test_store_PrevFinalizedCheckpt(t *testing.T) {
|
||||||
|
|||||||
@@ -17,9 +17,11 @@ import (
|
|||||||
// best_justified_checkpoint: Checkpoint
|
// best_justified_checkpoint: Checkpoint
|
||||||
// proposerBoostRoot: Root
|
// proposerBoostRoot: Root
|
||||||
type Store struct {
|
type Store struct {
|
||||||
justifiedCheckpt *ethpb.Checkpoint
|
justifiedCheckpt *ethpb.Checkpoint
|
||||||
finalizedCheckpt *ethpb.Checkpoint
|
justifiedPayloadBlockHash [32]byte
|
||||||
bestJustifiedCheckpt *ethpb.Checkpoint
|
finalizedCheckpt *ethpb.Checkpoint
|
||||||
|
finalizedPayloadBlockHash [32]byte
|
||||||
|
bestJustifiedCheckpt *ethpb.Checkpoint
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
// These are not part of the consensus spec, but we do use them to return gRPC API requests.
|
// These are not part of the consensus spec, but we do use them to return gRPC API requests.
|
||||||
// TODO(10094): Consider removing in v3.
|
// TODO(10094): Consider removing in v3.
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ go_library(
|
|||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/async/event"
|
"github.com/prysmaticlabs/prysm/async/event"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||||
@@ -22,9 +21,10 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ type ChainService struct {
|
|||||||
InitSyncBlockRoots map[[32]byte]bool
|
InitSyncBlockRoots map[[32]byte]bool
|
||||||
DB db.Database
|
DB db.Database
|
||||||
State state.BeaconState
|
State state.BeaconState
|
||||||
Block block.SignedBeaconBlock
|
Block interfaces.SignedBeaconBlock
|
||||||
VerifyBlkDescendantErr error
|
VerifyBlkDescendantErr error
|
||||||
stateNotifier statefeed.Notifier
|
stateNotifier statefeed.Notifier
|
||||||
BlocksReceived []block.SignedBeaconBlock
|
BlocksReceived []interfaces.SignedBeaconBlock
|
||||||
SyncCommitteeIndices []types.CommitteeIndex
|
SyncCommitteeIndices []types.CommitteeIndex
|
||||||
blockNotifier blockfeed.Notifier
|
blockNotifier blockfeed.Notifier
|
||||||
opNotifier opfeed.Notifier
|
opNotifier opfeed.Notifier
|
||||||
@@ -165,7 +165,7 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
|
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
|
||||||
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block block.SignedBeaconBlock, _ [32]byte) error {
|
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
|
||||||
if s.State == nil {
|
if s.State == nil {
|
||||||
return ErrNilState
|
return ErrNilState
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block block.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveBlockBatch processes blocks in batches from initial-sync.
|
// ReceiveBlockBatch processes blocks in batches from initial-sync.
|
||||||
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []block.SignedBeaconBlock, _ [][32]byte) error {
|
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock, _ [][32]byte) error {
|
||||||
if s.State == nil {
|
if s.State == nil {
|
||||||
return ErrNilState
|
return ErrNilState
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []block.Signe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveBlock mocks ReceiveBlock method in chain service.
|
// ReceiveBlock mocks ReceiveBlock method in chain service.
|
||||||
func (s *ChainService) ReceiveBlock(ctx context.Context, block block.SignedBeaconBlock, _ [32]byte) error {
|
func (s *ChainService) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
|
||||||
if s.ReceiveBlockMockErr != nil {
|
if s.ReceiveBlockMockErr != nil {
|
||||||
return s.ReceiveBlockMockErr
|
return s.ReceiveBlockMockErr
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ func (s *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HeadBlock mocks HeadBlock method in chain service.
|
// HeadBlock mocks HeadBlock method in chain service.
|
||||||
func (s *ChainService) HeadBlock(context.Context) (block.SignedBeaconBlock, error) {
|
func (s *ChainService) HeadBlock(context.Context) (interfaces.SignedBeaconBlock, error) {
|
||||||
return s.Block, nil
|
return s.Block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,11 +301,6 @@ func (_ *ChainService) ReceiveAttestation(_ context.Context, _ *ethpb.Attestatio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveAttestationNoPubsub mocks ReceiveAttestationNoPubsub method in chain service.
|
|
||||||
func (_ *ChainService) ReceiveAttestationNoPubsub(context.Context, *ethpb.Attestation) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AttestationTargetState mocks AttestationTargetState method in chain service.
|
// AttestationTargetState mocks AttestationTargetState method in chain service.
|
||||||
func (s *ChainService) AttestationTargetState(_ context.Context, _ *ethpb.Checkpoint) (state.BeaconState, error) {
|
func (s *ChainService) AttestationTargetState(_ context.Context, _ *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
return s.State, nil
|
return s.State, nil
|
||||||
@@ -319,11 +314,6 @@ func (s *ChainService) HeadValidatorsIndices(ctx context.Context, epoch types.Ep
|
|||||||
return helpers.ActiveValidatorIndices(ctx, s.State, epoch)
|
return helpers.ActiveValidatorIndices(ctx, s.State, epoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadSeed mocks the same method in the chain service.
|
|
||||||
func (s *ChainService) HeadSeed(_ context.Context, epoch types.Epoch) ([32]byte, error) {
|
|
||||||
return helpers.Seed(s.State, epoch, params.BeaconConfig().DomainBeaconAttester)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HeadETH1Data provides the current ETH1Data of the head state.
|
// HeadETH1Data provides the current ETH1Data of the head state.
|
||||||
func (s *ChainService) HeadETH1Data() *ethpb.Eth1Data {
|
func (s *ChainService) HeadETH1Data() *ethpb.Eth1Data {
|
||||||
return s.ETH1Data
|
return s.ETH1Data
|
||||||
@@ -367,8 +357,14 @@ func (s *ChainService) IsCanonical(_ context.Context, r [32]byte) (bool, error)
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasInitSyncBlock mocks the same method in the chain service.
|
// HasBlock mocks the same method in the chain service.
|
||||||
func (s *ChainService) HasInitSyncBlock(rt [32]byte) bool {
|
func (s *ChainService) HasBlock(ctx context.Context, rt [32]byte) bool {
|
||||||
|
if s.DB == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if s.DB.HasBlock(ctx, rt) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if s.InitSyncBlockRoots == nil {
|
if s.InitSyncBlockRoots == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -381,7 +377,7 @@ func (_ *ChainService) HeadGenesisValidatorsRoot() [32]byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VerifyBlkDescendant mocks VerifyBlkDescendant and always returns nil.
|
// VerifyBlkDescendant mocks VerifyBlkDescendant and always returns nil.
|
||||||
func (s *ChainService) VerifyBlkDescendant(_ context.Context, _ [32]byte) error {
|
func (s *ChainService) VerifyFinalizedBlkDescendant(_ context.Context, _ [32]byte) error {
|
||||||
return s.VerifyBlkDescendantErr
|
return s.VerifyBlkDescendantErr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,3 +450,9 @@ func (s *ChainService) IsOptimistic(_ context.Context) (bool, error) {
|
|||||||
func (s *ChainService) IsOptimisticForRoot(_ context.Context, _ [32]byte) (bool, error) {
|
func (s *ChainService) IsOptimisticForRoot(_ context.Context, _ [32]byte) (bool, error) {
|
||||||
return s.Optimistic, nil
|
return s.Optimistic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessAttestationsAndUpdateHead mocks the same method in the chain service.
|
||||||
|
func (s *ChainService) UpdateHead(_ context.Context) error { return nil }
|
||||||
|
|
||||||
|
// ReceiveAttesterSlashing mocks the same method in the chain service.
|
||||||
|
func (s *ChainService) ReceiveAttesterSlashing(context.Context, *ethpb.AttesterSlashing) {}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
@@ -32,9 +32,6 @@ type WeakSubjectivityVerifier struct {
|
|||||||
|
|
||||||
// NewWeakSubjectivityVerifier validates a checkpoint, and if valid, uses it to initialize a weak subjectivity verifier
|
// NewWeakSubjectivityVerifier validates a checkpoint, and if valid, uses it to initialize a weak subjectivity verifier
|
||||||
func NewWeakSubjectivityVerifier(wsc *ethpb.Checkpoint, db weakSubjectivityDB) (*WeakSubjectivityVerifier, error) {
|
func NewWeakSubjectivityVerifier(wsc *ethpb.Checkpoint, db weakSubjectivityDB) (*WeakSubjectivityVerifier, error) {
|
||||||
// TODO(7342): Weak subjectivity checks are currently optional. When we require the flag to be specified
|
|
||||||
// per 7342, a nil checkpoint, zero-root or zero-epoch should all fail validation
|
|
||||||
// and return an error instead of creating a WeakSubjectivityVerifier that permits any chain history.
|
|
||||||
if wsc == nil || len(wsc.Root) == 0 || wsc.Epoch == 0 {
|
if wsc == nil || len(wsc.Root) == 0 || wsc.Epoch == 0 {
|
||||||
log.Warn("No valid weak subjectivity checkpoint specified, running without weak subjectivity verification")
|
log.Warn("No valid weak subjectivity checkpoint specified, running without weak subjectivity verification")
|
||||||
return &WeakSubjectivityVerifier{
|
return &WeakSubjectivityVerifier{
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
||||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
"github.com/prysmaticlabs/prysm/time/slots"
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
@@ -79,7 +79,7 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
|||||||
store: &store.Store{},
|
store: &store.Store{},
|
||||||
wsVerifier: wv,
|
wsVerifier: wv,
|
||||||
}
|
}
|
||||||
s.store.SetFinalizedCheckpt(ðpb.Checkpoint{Epoch: tt.finalizedEpoch})
|
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: tt.finalizedEpoch}, [32]byte{})
|
||||||
err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), s.store.FinalizedCheckpt().Epoch)
|
err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), s.store.FinalizedCheckpt().Epoch)
|
||||||
if tt.wantErr == nil {
|
if tt.wantErr == nil {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
6
beacon-chain/cache/BUILD.bazel
vendored
6
beacon-chain/cache/BUILD.bazel
vendored
@@ -33,8 +33,8 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//cache/lru:go_default_library",
|
"//cache/lru:go_default_library",
|
||||||
"//config/features:go_default_library",
|
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//container/slice:go_default_library",
|
"//container/slice:go_default_library",
|
||||||
"//crypto/hash:go_default_library",
|
"//crypto/hash:go_default_library",
|
||||||
"//crypto/rand:go_default_library",
|
"//crypto/rand:go_default_library",
|
||||||
@@ -47,7 +47,6 @@ go_library(
|
|||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@io_k8s_client_go//tools/cache:go_default_library",
|
"@io_k8s_client_go//tools/cache:go_default_library",
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -77,16 +76,15 @@ go_test(
|
|||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//beacon-chain/state/v2:go_default_library",
|
"//beacon-chain/state/v2:go_default_library",
|
||||||
"//beacon-chain/state/v3:go_default_library",
|
"//beacon-chain/state/v3:go_default_library",
|
||||||
"//config/features:go_default_library",
|
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
"@com_github_google_gofuzz//:go_default_library",
|
"@com_github_google_gofuzz//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
9
beacon-chain/cache/active_balance.go
vendored
9
beacon-chain/cache/active_balance.go
vendored
@@ -11,11 +11,10 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
ethTypes "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
ethTypes "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -51,9 +50,6 @@ func NewEffectiveBalanceCache() *BalanceCache {
|
|||||||
|
|
||||||
// AddTotalEffectiveBalance adds a new total effective balance entry for current balance for state `st` into the cache.
|
// AddTotalEffectiveBalance adds a new total effective balance entry for current balance for state `st` into the cache.
|
||||||
func (c *BalanceCache) AddTotalEffectiveBalance(st state.ReadOnlyBeaconState, balance uint64) error {
|
func (c *BalanceCache) AddTotalEffectiveBalance(st state.ReadOnlyBeaconState, balance uint64) error {
|
||||||
if !features.Get().EnableActiveBalanceCache {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
key, err := balanceCacheKey(st)
|
key, err := balanceCacheKey(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -68,9 +64,6 @@ func (c *BalanceCache) AddTotalEffectiveBalance(st state.ReadOnlyBeaconState, ba
|
|||||||
|
|
||||||
// Get returns the current epoch's effective balance for state `st` in cache.
|
// Get returns the current epoch's effective balance for state `st` in cache.
|
||||||
func (c *BalanceCache) Get(st state.ReadOnlyBeaconState) (uint64, error) {
|
func (c *BalanceCache) Get(st state.ReadOnlyBeaconState) (uint64, error) {
|
||||||
if !features.Get().EnableActiveBalanceCache {
|
|
||||||
return 0, ErrNotFound
|
|
||||||
}
|
|
||||||
key, err := balanceCacheKey(st)
|
key, err := balanceCacheKey(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|||||||
11
beacon-chain/cache/active_balance_test.go
vendored
11
beacon-chain/cache/active_balance_test.go
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build !fuzz
|
||||||
|
// +build !fuzz
|
||||||
|
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,20 +8,14 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
state "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
state "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBalanceCache_AddGetBalance(t *testing.T) {
|
func TestBalanceCache_AddGetBalance(t *testing.T) {
|
||||||
resetCfg := features.InitWithReset(&features.Flags{
|
|
||||||
EnableActiveBalanceCache: true,
|
|
||||||
})
|
|
||||||
defer resetCfg()
|
|
||||||
|
|
||||||
blockRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot)
|
blockRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot)
|
||||||
for i := 0; i < len(blockRoots); i++ {
|
for i := 0; i < len(blockRoots); i++ {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
|
|||||||
2
beacon-chain/cache/checkpoint_state_test.go
vendored
2
beacon-chain/cache/checkpoint_state_test.go
vendored
@@ -3,10 +3,10 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
|||||||
2
beacon-chain/cache/committee.go
vendored
2
beacon-chain/cache/committee.go
vendored
@@ -13,9 +13,9 @@ import (
|
|||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/container/slice"
|
"github.com/prysmaticlabs/prysm/container/slice"
|
||||||
mathutil "github.com/prysmaticlabs/prysm/math"
|
mathutil "github.com/prysmaticlabs/prysm/math"
|
||||||
)
|
)
|
||||||
|
|||||||
2
beacon-chain/cache/committee_disabled.go
vendored
2
beacon-chain/cache/committee_disabled.go
vendored
@@ -7,7 +7,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FakeCommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
|
// FakeCommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
|
||||||
|
|||||||
3
beacon-chain/cache/committee_fuzz_test.go
vendored
3
beacon-chain/cache/committee_fuzz_test.go
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build !fuzz
|
||||||
|
// +build !fuzz
|
||||||
|
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
5
beacon-chain/cache/committee_test.go
vendored
5
beacon-chain/cache/committee_test.go
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build !fuzz
|
||||||
|
// +build !fuzz
|
||||||
|
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -7,8 +10,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
|||||||
2
beacon-chain/cache/committees.go
vendored
2
beacon-chain/cache/committees.go
vendored
@@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotCommittee will be returned when a cache object is not a pointer to
|
// ErrNotCommittee will be returned when a cache object is not a pointer to
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type DepositFetcher interface {
|
|||||||
DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int)
|
DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int)
|
||||||
DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte)
|
DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte)
|
||||||
FinalizedDeposits(ctx context.Context) *FinalizedDeposits
|
FinalizedDeposits(ctx context.Context) *FinalizedDeposits
|
||||||
NonFinalizedDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
|
NonFinalizedDeposits(ctx context.Context, lastFinalizedIndex int64, untilBlk *big.Int) []*ethpb.Deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalizedDeposits stores the trie of deposits that have been included
|
// FinalizedDeposits stores the trie of deposits that have been included
|
||||||
@@ -137,6 +137,22 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
|
|||||||
|
|
||||||
depositTrie := dc.finalizedDeposits.Deposits
|
depositTrie := dc.finalizedDeposits.Deposits
|
||||||
insertIndex := int(dc.finalizedDeposits.MerkleTrieIndex + 1)
|
insertIndex := int(dc.finalizedDeposits.MerkleTrieIndex + 1)
|
||||||
|
|
||||||
|
// Don't insert into finalized trie if there is no deposit to
|
||||||
|
// insert.
|
||||||
|
if len(dc.deposits) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// In the event we have less deposits than we need to
|
||||||
|
// finalize we finalize till the index on which we do have it.
|
||||||
|
if len(dc.deposits) <= int(eth1DepositIndex) {
|
||||||
|
eth1DepositIndex = int64(len(dc.deposits)) - 1
|
||||||
|
}
|
||||||
|
// If we finalize to some lower deposit index, we
|
||||||
|
// ignore it.
|
||||||
|
if int(eth1DepositIndex) < insertIndex {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, d := range dc.deposits {
|
for _, d := range dc.deposits {
|
||||||
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
|
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
|
||||||
continue
|
continue
|
||||||
@@ -246,7 +262,7 @@ func (dc *DepositCache) FinalizedDeposits(ctx context.Context) *FinalizedDeposit
|
|||||||
|
|
||||||
// NonFinalizedDeposits returns the list of non-finalized deposits until the given block number (inclusive).
|
// NonFinalizedDeposits returns the list of non-finalized deposits until the given block number (inclusive).
|
||||||
// If no block is specified then this method returns all non-finalized deposits.
|
// If no block is specified then this method returns all non-finalized deposits.
|
||||||
func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, lastFinalizedIndex int64, untilBlk *big.Int) []*ethpb.Deposit {
|
||||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.NonFinalizedDeposits")
|
ctx, span := trace.StartSpan(ctx, "DepositsCache.NonFinalizedDeposits")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
dc.depositsLock.RLock()
|
dc.depositsLock.RLock()
|
||||||
@@ -256,10 +272,9 @@ func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, untilBlk *big.
|
|||||||
return dc.allDeposits(untilBlk)
|
return dc.allDeposits(untilBlk)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastFinalizedDepositIndex := dc.finalizedDeposits.MerkleTrieIndex
|
|
||||||
var deposits []*ethpb.Deposit
|
var deposits []*ethpb.Deposit
|
||||||
for _, d := range dc.deposits {
|
for _, d := range dc.deposits {
|
||||||
if (d.Index > lastFinalizedDepositIndex) && (untilBlk == nil || untilBlk.Uint64() >= d.Eth1BlockHeight) {
|
if (d.Index > lastFinalizedIndex) && (untilBlk == nil || untilBlk.Uint64() >= d.Eth1BlockHeight) {
|
||||||
deposits = append(deposits, d.Deposit)
|
deposits = append(deposits, d.Deposit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,7 +430,11 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
|
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
|
||||||
require.NoError(t, err, "Could not generate deposit trie")
|
require.NoError(t, err, "Could not generate deposit trie")
|
||||||
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
|
rootA, err := trie.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, rootA, rootB)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
||||||
@@ -459,7 +463,7 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
|||||||
Index: 1,
|
Index: 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
newFinalizedDeposit := ethpb.DepositContainer{
|
newFinalizedDeposit := ðpb.DepositContainer{
|
||||||
Deposit: ðpb.Deposit{
|
Deposit: ðpb.Deposit{
|
||||||
Data: ðpb.Deposit_Data{
|
Data: ðpb.Deposit_Data{
|
||||||
PublicKey: bytesutil.PadTo([]byte{2}, 48),
|
PublicKey: bytesutil.PadTo([]byte{2}, 48),
|
||||||
@@ -471,24 +475,162 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
dc.deposits = oldFinalizedDeposits
|
dc.deposits = oldFinalizedDeposits
|
||||||
dc.InsertFinalizedDeposits(context.Background(), 1)
|
dc.InsertFinalizedDeposits(context.Background(), 1)
|
||||||
// Artificially exclude old deposits so that they can only be retrieved from previously finalized deposits.
|
|
||||||
dc.deposits = []*ethpb.DepositContainer{&newFinalizedDeposit}
|
|
||||||
|
|
||||||
dc.InsertFinalizedDeposits(context.Background(), 2)
|
dc.InsertFinalizedDeposits(context.Background(), 2)
|
||||||
|
|
||||||
|
dc.deposits = append(dc.deposits, []*ethpb.DepositContainer{newFinalizedDeposit}...)
|
||||||
|
|
||||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||||
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
|
assert.Equal(t, int64(1), cachedDeposits.MerkleTrieIndex)
|
||||||
|
|
||||||
var deps [][]byte
|
var deps [][]byte
|
||||||
for _, d := range append(oldFinalizedDeposits, &newFinalizedDeposit) {
|
for _, d := range oldFinalizedDeposits {
|
||||||
hash, err := d.Deposit.Data.HashTreeRoot()
|
hash, err := d.Deposit.Data.HashTreeRoot()
|
||||||
require.NoError(t, err, "Could not hash deposit data")
|
require.NoError(t, err, "Could not hash deposit data")
|
||||||
deps = append(deps, hash[:])
|
deps = append(deps, hash[:])
|
||||||
}
|
}
|
||||||
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
|
trie, err := trie.GenerateTrieFromItems(deps, params.BeaconConfig().DepositContractTreeDepth)
|
||||||
require.NoError(t, err, "Could not generate deposit trie")
|
require.NoError(t, err, "Could not generate deposit trie")
|
||||||
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
|
rootA, err := trie.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, rootA, rootB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFinalizedDeposits_HandleZeroDeposits(t *testing.T) {
|
||||||
|
dc, err := New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 2)
|
||||||
|
|
||||||
|
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||||
|
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||||
|
assert.Equal(t, int64(-1), cachedDeposits.MerkleTrieIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFinalizedDeposits_HandleSmallerThanExpectedDeposits(t *testing.T) {
|
||||||
|
dc, err := New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
finalizedDeposits := []*ethpb.DepositContainer{
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{0}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{1}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{2}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dc.deposits = finalizedDeposits
|
||||||
|
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 5)
|
||||||
|
|
||||||
|
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||||
|
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||||
|
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFinalizedDeposits_HandleLowerEth1DepositIndex(t *testing.T) {
|
||||||
|
dc, err := New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
finalizedDeposits := []*ethpb.DepositContainer{
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{0}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{1}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{2}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{3}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{4}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{5}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dc.deposits = finalizedDeposits
|
||||||
|
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 5)
|
||||||
|
|
||||||
|
// Reinsert finalized deposits with a lower index.
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 2)
|
||||||
|
|
||||||
|
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||||
|
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||||
|
assert.Equal(t, int64(5), cachedDeposits.MerkleTrieIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
|
func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
|
||||||
@@ -554,7 +696,7 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
|
|||||||
})
|
})
|
||||||
dc.InsertFinalizedDeposits(context.Background(), 1)
|
dc.InsertFinalizedDeposits(context.Background(), 1)
|
||||||
|
|
||||||
deps := dc.NonFinalizedDeposits(context.Background(), nil)
|
deps := dc.NonFinalizedDeposits(context.Background(), 1, nil)
|
||||||
assert.Equal(t, 2, len(deps))
|
assert.Equal(t, 2, len(deps))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,10 +753,89 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
|
|||||||
})
|
})
|
||||||
dc.InsertFinalizedDeposits(context.Background(), 1)
|
dc.InsertFinalizedDeposits(context.Background(), 1)
|
||||||
|
|
||||||
deps := dc.NonFinalizedDeposits(context.Background(), big.NewInt(10))
|
deps := dc.NonFinalizedDeposits(context.Background(), 1, big.NewInt(10))
|
||||||
assert.Equal(t, 1, len(deps))
|
assert.Equal(t, 1, len(deps))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFinalizedDeposits_ReturnsTrieCorrectly(t *testing.T) {
|
||||||
|
dc, err := New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
generateCtr := func(height uint64, index int64) *ethpb.DepositContainer {
|
||||||
|
return ðpb.DepositContainer{
|
||||||
|
Eth1BlockHeight: height,
|
||||||
|
Deposit: ðpb.Deposit{
|
||||||
|
Data: ðpb.Deposit_Data{
|
||||||
|
PublicKey: bytesutil.PadTo([]byte{uint8(index)}, 48),
|
||||||
|
WithdrawalCredentials: make([]byte, 32),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finalizedDeposits := []*ethpb.DepositContainer{
|
||||||
|
generateCtr(10, 0),
|
||||||
|
generateCtr(11, 1),
|
||||||
|
generateCtr(12, 2),
|
||||||
|
generateCtr(12, 3),
|
||||||
|
generateCtr(13, 4),
|
||||||
|
generateCtr(13, 5),
|
||||||
|
generateCtr(13, 6),
|
||||||
|
generateCtr(14, 7),
|
||||||
|
}
|
||||||
|
dc.deposits = append(finalizedDeposits,
|
||||||
|
generateCtr(15, 8),
|
||||||
|
generateCtr(15, 9),
|
||||||
|
generateCtr(30, 10))
|
||||||
|
trieItems := make([][]byte, 0, len(dc.deposits))
|
||||||
|
for _, dep := range dc.allDeposits(big.NewInt(30)) {
|
||||||
|
depHash, err := dep.Data.HashTreeRoot()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
trieItems = append(trieItems, depHash[:])
|
||||||
|
}
|
||||||
|
depositTrie, err := trie.GenerateTrieFromItems(trieItems, params.BeaconConfig().DepositContractTreeDepth)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Perform this in a non-sensical ordering
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 10)
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 2)
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 3)
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 4)
|
||||||
|
|
||||||
|
// Mimick finalized deposit trie fetch.
|
||||||
|
fd := dc.FinalizedDeposits(context.Background())
|
||||||
|
deps := dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex, big.NewInt(14))
|
||||||
|
insertIndex := fd.MerkleTrieIndex + 1
|
||||||
|
|
||||||
|
for _, dep := range deps {
|
||||||
|
depHash, err := dep.Data.HashTreeRoot()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if err = fd.Deposits.Insert(depHash[:], int(insertIndex)); err != nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
insertIndex++
|
||||||
|
}
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 15)
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 15)
|
||||||
|
dc.InsertFinalizedDeposits(context.Background(), 14)
|
||||||
|
|
||||||
|
fd = dc.FinalizedDeposits(context.Background())
|
||||||
|
deps = dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex, big.NewInt(30))
|
||||||
|
insertIndex = fd.MerkleTrieIndex + 1
|
||||||
|
|
||||||
|
for _, dep := range deps {
|
||||||
|
depHash, err := dep.Data.HashTreeRoot()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if err = fd.Deposits.Insert(depHash[:], int(insertIndex)); err != nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
insertIndex++
|
||||||
|
}
|
||||||
|
assert.Equal(t, fd.Deposits.NumOfItems(), depositTrie.NumOfItems())
|
||||||
|
}
|
||||||
|
|
||||||
func TestPruneProofs_Ok(t *testing.T) {
|
func TestPruneProofs_Ok(t *testing.T) {
|
||||||
dc, err := New()
|
dc, err := New()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
2
beacon-chain/cache/payload_id.go
vendored
2
beacon-chain/cache/payload_id.go
vendored
@@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
beacon-chain/cache/payload_id_test.go
vendored
2
beacon-chain/cache/payload_id_test.go
vendored
@@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
19
beacon-chain/cache/proposer_indices.go
vendored
19
beacon-chain/cache/proposer_indices.go
vendored
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ var (
|
|||||||
|
|
||||||
// ProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
|
// ProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
|
||||||
type ProposerIndicesCache struct {
|
type ProposerIndicesCache struct {
|
||||||
ProposerIndicesCache *cache.FIFO
|
proposerIndicesCache *cache.FIFO
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func proposerIndicesKeyFn(obj interface{}) (string, error) {
|
|||||||
// NewProposerIndicesCache creates a new proposer indices cache for storing/accessing proposer index assignments of an epoch.
|
// NewProposerIndicesCache creates a new proposer indices cache for storing/accessing proposer index assignments of an epoch.
|
||||||
func NewProposerIndicesCache() *ProposerIndicesCache {
|
func NewProposerIndicesCache() *ProposerIndicesCache {
|
||||||
return &ProposerIndicesCache{
|
return &ProposerIndicesCache{
|
||||||
ProposerIndicesCache: cache.NewFIFO(proposerIndicesKeyFn),
|
proposerIndicesCache: cache.NewFIFO(proposerIndicesKeyFn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,10 +58,10 @@ func (c *ProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error {
|
|||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
if err := c.ProposerIndicesCache.AddIfNotPresent(p); err != nil {
|
if err := c.proposerIndicesCache.AddIfNotPresent(p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
trim(c.ProposerIndicesCache, maxProposerIndicesCacheSize)
|
trim(c.proposerIndicesCache, maxProposerIndicesCacheSize)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ func (c *ProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error {
|
|||||||
func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
|
func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
defer c.lock.RUnlock()
|
defer c.lock.RUnlock()
|
||||||
_, exists, err := c.ProposerIndicesCache.GetByKey(key(r))
|
_, exists, err := c.proposerIndicesCache.GetByKey(key(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
|
|||||||
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
|
func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) {
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
defer c.lock.RUnlock()
|
defer c.lock.RUnlock()
|
||||||
obj, exists, err := c.ProposerIndicesCache.GetByKey(key(r))
|
obj, exists, err := c.proposerIndicesCache.GetByKey(key(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -99,3 +99,8 @@ func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorInd
|
|||||||
|
|
||||||
return item.ProposerIndices, nil
|
return item.ProposerIndices, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Len returns the number of keys in the underlying cache.
|
||||||
|
func (c *ProposerIndicesCache) Len() int {
|
||||||
|
return len(c.proposerIndicesCache.ListKeys())
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// This file is used in fuzzer builds to bypass proposer indices caches.
|
// This file is used in fuzzer builds to bypass proposer indices caches.
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import types "github.com/prysmaticlabs/eth2-types"
|
import types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
|
||||||
// FakeProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
|
// FakeProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root.
|
||||||
type FakeProposerIndicesCache struct {
|
type FakeProposerIndicesCache struct {
|
||||||
@@ -30,3 +30,7 @@ func (c *FakeProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.Validato
|
|||||||
func (c *FakeProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
|
func (c *FakeProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FakeProposerIndicesCache) Len() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|||||||
9
beacon-chain/cache/proposer_indices_test.go
vendored
9
beacon-chain/cache/proposer_indices_test.go
vendored
@@ -1,10 +1,13 @@
|
|||||||
|
//go:build !fuzz
|
||||||
|
// +build !fuzz
|
||||||
|
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
@@ -68,7 +71,5 @@ func TestProposerCache_CanRotate(t *testing.T) {
|
|||||||
item := &ProposerIndices{BlockRoot: bytesutil.ToBytes32(s)}
|
item := &ProposerIndices{BlockRoot: bytesutil.ToBytes32(s)}
|
||||||
require.NoError(t, cache.AddProposerIndices(item))
|
require.NoError(t, cache.AddProposerIndices(item))
|
||||||
}
|
}
|
||||||
|
assert.Equal(t, int(maxProposerIndicesCacheSize), cache.Len())
|
||||||
k := cache.ProposerIndicesCache.ListKeys()
|
|
||||||
assert.Equal(t, maxProposerIndicesCacheSize, uint64(len(k)))
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
beacon-chain/cache/proposer_indices_type.go
vendored
2
beacon-chain/cache/proposer_indices_type.go
vendored
@@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotProposerIndices will be returned when a cache object is not a pointer to
|
// ErrNotProposerIndices will be returned when a cache object is not a pointer to
|
||||||
|
|||||||
2
beacon-chain/cache/subnet_ids.go
vendored
2
beacon-chain/cache/subnet_ids.go
vendored
@@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/container/slice"
|
"github.com/prysmaticlabs/prysm/container/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
beacon-chain/cache/subnet_ids_test.go
vendored
2
beacon-chain/cache/subnet_ids_test.go
vendored
@@ -3,8 +3,8 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|||||||
2
beacon-chain/cache/sync_committee.go
vendored
2
beacon-chain/cache/sync_committee.go
vendored
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FakeSyncCommitteeCache is a fake `SyncCommitteeCache` to satisfy fuzzing.
|
// FakeSyncCommitteeCache is a fake `SyncCommitteeCache` to satisfy fuzzing.
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|||||||
2
beacon-chain/cache/sync_committee_test.go
vendored
2
beacon-chain/cache/sync_committee_test.go
vendored
@@ -3,8 +3,8 @@ package cache_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
|
|||||||
2
beacon-chain/cache/sync_subnet_ids.go
vendored
2
beacon-chain/cache/sync_subnet_ids.go
vendored
@@ -5,8 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/container/slice"
|
"github.com/prysmaticlabs/prysm/container/slice"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/rand"
|
"github.com/prysmaticlabs/prysm/crypto/rand"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ go_library(
|
|||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/altair",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/altair",
|
||||||
visibility = [
|
visibility = [
|
||||||
"//beacon-chain:__subpackages__",
|
"//beacon-chain:__subpackages__",
|
||||||
|
"//testing/endtoend/evaluators:__subpackages__",
|
||||||
"//testing/spectest:__subpackages__",
|
"//testing/spectest:__subpackages__",
|
||||||
"//testing/util:__pkg__",
|
"//testing/util:__pkg__",
|
||||||
"//validator/client:__pkg__",
|
"//validator/client:__pkg__",
|
||||||
@@ -32,17 +33,17 @@ go_library(
|
|||||||
"//beacon-chain/state/v2:go_default_library",
|
"//beacon-chain/state/v2:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
"//crypto/hash:go_default_library",
|
"//crypto/hash:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//math:go_default_library",
|
"//math:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
],
|
],
|
||||||
@@ -75,20 +76,20 @@ go_test(
|
|||||||
"//beacon-chain/state/v3:go_default_library",
|
"//beacon-chain/state/v3:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//container/trie:go_default_library",
|
"//container/trie:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
"//math:go_default_library",
|
"//math:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
"//testing/util:go_default_library",
|
"//testing/util:go_default_library",
|
||||||
"//time:go_default_library",
|
"//time:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_google_gofuzz//:go_default_library",
|
"@com_github_google_gofuzz//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
func ProcessAttestationsNoVerifySignature(
|
func ProcessAttestationsNoVerifySignature(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
beaconState state.BeaconState,
|
beaconState state.BeaconState,
|
||||||
b block.SignedBeaconBlock,
|
b interfaces.SignedBeaconBlock,
|
||||||
) (state.BeaconState, error) {
|
) (state.BeaconState, error) {
|
||||||
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fuzz "github.com/google/gofuzz"
|
fuzz "github.com/google/gofuzz"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
@@ -16,11 +15,12 @@ import (
|
|||||||
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/math"
|
"github.com/prysmaticlabs/prysm/math"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
p2pType "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
p2pType "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
p2pType "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
p2pType "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
balances := []uint64{0, 50}
|
balances := []uint64{0, 50}
|
||||||
root := depositTrie.HashTreeRoot()
|
root, err := depositTrie.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
beaconState, err := stateAltair.InitializeFromProto(ðpb.BeaconStateAltair{
|
beaconState, err := stateAltair.InitializeFromProto(ðpb.BeaconStateAltair{
|
||||||
Validators: registry,
|
Validators: registry,
|
||||||
Balances: balances,
|
Balances: balances,
|
||||||
@@ -202,7 +203,8 @@ func TestProcessDeposit_SkipsInvalidDeposit(t *testing.T) {
|
|||||||
dep[0].Data.Signature = make([]byte, 96)
|
dep[0].Data.Signature = make([]byte, 96)
|
||||||
trie, _, err := util.DepositTrieFromDeposits(dep)
|
trie, _, err := util.DepositTrieFromDeposits(dep)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
root := trie.HashTreeRoot()
|
root, err := trie.HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
eth1Data := ðpb.Eth1Data{
|
eth1Data := ðpb.Eth1Data{
|
||||||
DepositRoot: root[:],
|
DepositRoot: root[:],
|
||||||
DepositCount: 1,
|
DepositCount: 1,
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package altair
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/math"
|
"github.com/prysmaticlabs/prysm/math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
coreTime "github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
coreTime "github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ go_library(
|
|||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/interfaces:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//container/slice:go_default_library",
|
"//container/slice:go_default_library",
|
||||||
"//container/trie:go_default_library",
|
"//container/trie:go_default_library",
|
||||||
"//contracts/deposit:go_default_library",
|
"//contracts/deposit:go_default_library",
|
||||||
@@ -43,13 +46,10 @@ go_library(
|
|||||||
"//proto/engine/v1:go_default_library",
|
"//proto/engine/v1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1/slashings:go_default_library",
|
"//proto/prysm/v1alpha1/slashings:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
@@ -89,6 +89,8 @@ go_test(
|
|||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
|
"//consensus-types/primitives:go_default_library",
|
||||||
|
"//consensus-types/wrapper:go_default_library",
|
||||||
"//container/trie:go_default_library",
|
"//container/trie:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
@@ -98,7 +100,6 @@ go_test(
|
|||||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation/aggregation:go_default_library",
|
"//proto/prysm/v1alpha1/attestation/aggregation:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/attestation/aggregation/attestations:go_default_library",
|
"//proto/prysm/v1alpha1/attestation/aggregation/attestations:go_default_library",
|
||||||
"//proto/prysm/v1alpha1/wrapper:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"//testing/assert:go_default_library",
|
"//testing/assert:go_default_library",
|
||||||
"//testing/require:go_default_library",
|
"//testing/require:go_default_library",
|
||||||
@@ -106,7 +107,6 @@ go_test(
|
|||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_google_gofuzz//:go_default_library",
|
"@com_github_google_gofuzz//:go_default_library",
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
func ProcessAttestationsNoVerifySignature(
|
func ProcessAttestationsNoVerifySignature(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
beaconState state.BeaconState,
|
beaconState state.BeaconState,
|
||||||
b block.SignedBeaconBlock,
|
b interfaces.SignedBeaconBlock,
|
||||||
) (state.BeaconState, error) {
|
) (state.BeaconState, error) {
|
||||||
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
if err := helpers.BeaconBlockIsNil(b); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package blocks_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
// valid att.Data.Committee index would be 0, so this is an off by one error.
|
// valid att.Data.Committee index would be 0, so this is an off by one error.
|
||||||
// See: https://github.com/sigp/beacon-fuzz/issues/78
|
// See: https://github.com/sigp/beacon-fuzz/issues/78
|
||||||
func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
|
func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
|
||||||
attData, err := ioutil.ReadFile("testdata/beaconfuzz_78_attestation.ssz")
|
attData, err := os.ReadFile("testdata/beaconfuzz_78_attestation.ssz")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
|
|||||||
if err := att.UnmarshalSSZ(attData); err != nil {
|
if err := att.UnmarshalSSZ(attData); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
stateData, err := ioutil.ReadFile("testdata/beaconfuzz_78_beacon.ssz")
|
stateData, err := os.ReadFile("testdata/beaconfuzz_78_beacon.ssz")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
@@ -12,6 +11,7 @@ import (
|
|||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/container/slice"
|
"github.com/prysmaticlabs/prysm/container/slice"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fuzz "github.com/google/gofuzz"
|
fuzz "github.com/google/gofuzz"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
|
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user