mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
170 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fd5575f65 | ||
|
|
f5428a2c60 | ||
|
|
7a6ce27497 | ||
|
|
6eb006175a | ||
|
|
8f90e91e99 | ||
|
|
644d5bbb1a | ||
|
|
0d8dd8d280 | ||
|
|
bb6f00fd87 | ||
|
|
f2768c1414 | ||
|
|
a81c4ed6a0 | ||
|
|
26c4e7b527 | ||
|
|
aa4c21d6df | ||
|
|
833ac0092c | ||
|
|
2ee5bd12cf | ||
|
|
d4aa4bc258 | ||
|
|
1ea042dd6e | ||
|
|
dd10a3ab5d | ||
|
|
8d428606a2 | ||
|
|
8433a313f0 | ||
|
|
693fdf87bb | ||
|
|
5aac06f04e | ||
|
|
1d2fc60ba7 | ||
|
|
2b6c7e7b37 | ||
|
|
fc898d541f | ||
|
|
91bd477f4f | ||
|
|
ef20f2da7e | ||
|
|
8a6e2a33a2 | ||
|
|
eb1d122aec | ||
|
|
638e76cbd7 | ||
|
|
bb8625ede5 | ||
|
|
40b4079924 | ||
|
|
6bb3cc45ef | ||
|
|
e97f6cfdbf | ||
|
|
d5f4385525 | ||
|
|
8094c1c4c5 | ||
|
|
276d03553c | ||
|
|
caf9bdbc6f | ||
|
|
7b55213e6d | ||
|
|
d5ad15ed80 | ||
|
|
2e322bdf6d | ||
|
|
5fe98ab260 | ||
|
|
a958dd246b | ||
|
|
aa0fb058c6 | ||
|
|
0cbdce6bd6 | ||
|
|
5ae6e83c7f | ||
|
|
180b8447f7 | ||
|
|
503ec126e1 | ||
|
|
76cdbaca22 | ||
|
|
09d7efe964 | ||
|
|
7dc3d7fc60 | ||
|
|
59897b78ff | ||
|
|
f4d6e91e72 | ||
|
|
213369f5d0 | ||
|
|
8aa909de2d | ||
|
|
36e9edd654 | ||
|
|
9db4eba72b | ||
|
|
fe440bc0eb | ||
|
|
f68e0846ba | ||
|
|
f2a2d5d43c | ||
|
|
f2fe1f7683 | ||
|
|
35dc8c31fa | ||
|
|
519e1e4f4a | ||
|
|
2f10b1c7b1 | ||
|
|
e254e8edcc | ||
|
|
e6a1d5b1b9 | ||
|
|
bc27a73600 | ||
|
|
4ef5c9ad15 | ||
|
|
ddab82e52a | ||
|
|
8fe26e7c84 | ||
|
|
f97c7ee1da | ||
|
|
ad4fadb36a | ||
|
|
255354f27e | ||
|
|
050b244fa6 | ||
|
|
ab6d8486fb | ||
|
|
b628b5f8ca | ||
|
|
ac4fe2db5a | ||
|
|
2f66d1a46c | ||
|
|
60c6cf7438 | ||
|
|
8dd2915d3c | ||
|
|
3c9b9e7bf5 | ||
|
|
a090650446 | ||
|
|
dace0f9b10 | ||
|
|
a6e1ff0e63 | ||
|
|
1dde588932 | ||
|
|
54d4d39ea1 | ||
|
|
7be6fc1780 | ||
|
|
2fdfda2804 | ||
|
|
a063952abe | ||
|
|
1a00121e60 | ||
|
|
8fffa6c92a | ||
|
|
64bd9dba9b | ||
|
|
f2767f4f8d | ||
|
|
71f53d908f | ||
|
|
7b8e48d80e | ||
|
|
b6c50df435 | ||
|
|
9b697d2c12 | ||
|
|
d1a952a6fc | ||
|
|
58a81c704b | ||
|
|
5c9f361903 | ||
|
|
ef9f6c5b4d | ||
|
|
424e115331 | ||
|
|
f1d7c0f2c9 | ||
|
|
3d96e3c142 | ||
|
|
8cda50f179 | ||
|
|
3574ee177d | ||
|
|
386b69f473 | ||
|
|
648e360842 | ||
|
|
23ff14c34b | ||
|
|
e52df323f7 | ||
|
|
823f7c99d2 | ||
|
|
711f527efb | ||
|
|
af8f444166 | ||
|
|
2634430f67 | ||
|
|
70dc22aa9a | ||
|
|
ad269ee147 | ||
|
|
cff7dbd015 | ||
|
|
afc0ace624 | ||
|
|
400e42cc2d | ||
|
|
59ee339497 | ||
|
|
c53d0e1c5f | ||
|
|
02a8ae7f36 | ||
|
|
a4ff97d24b | ||
|
|
3d3b9d1217 | ||
|
|
169cd78bbd | ||
|
|
405e2a1a03 | ||
|
|
d77c298ec6 | ||
|
|
2c6549b431 | ||
|
|
aba2ec9aac | ||
|
|
a8716d2949 | ||
|
|
04bc8a85ca | ||
|
|
a9a0ecd76d | ||
|
|
902e3f4f53 | ||
|
|
228033f7a3 | ||
|
|
53ffc67850 | ||
|
|
59eb2e60d0 | ||
|
|
0ea11ac212 | ||
|
|
3e686a71e3 | ||
|
|
efbefaeb7c | ||
|
|
dd7481e99c | ||
|
|
fda003288d | ||
|
|
131a14ee2f | ||
|
|
45d2df1af7 | ||
|
|
5f3299e598 | ||
|
|
5217081567 | ||
|
|
389bad7d24 | ||
|
|
97b4b86ddf | ||
|
|
cc9bec7a19 | ||
|
|
8b494fb1bc | ||
|
|
6aa1297829 | ||
|
|
a91f2688f1 | ||
|
|
1c1bf37b33 | ||
|
|
76e36b95f7 | ||
|
|
74cf2320ad | ||
|
|
2a1c880673 | ||
|
|
c65c6ebc38 | ||
|
|
19a9b4b064 | ||
|
|
1af88b2c35 | ||
|
|
e3149c4f0b | ||
|
|
0808c02c65 | ||
|
|
76390c94af | ||
|
|
f0e2f561d5 | ||
|
|
74d0134ee3 | ||
|
|
91df0112c7 | ||
|
|
7998348bcb | ||
|
|
99bd988375 | ||
|
|
0a2f3e4d48 | ||
|
|
dfe5372db5 | ||
|
|
f2f509be0e | ||
|
|
01eb77c834 | ||
|
|
3cd95b4a6c |
13
.bazelrc
13
.bazelrc
@@ -39,16 +39,15 @@ build --define kafka_enabled=false
|
||||
test --define kafka_enabled=false
|
||||
run --define kafka_enabled=false
|
||||
|
||||
# Enable blst by default, we use a config so that our fuzzer stops complaining.
|
||||
build --config=blst_enabled
|
||||
test --config=blst_enabled
|
||||
run --config=blst_enabled
|
||||
build --define blst_disabled=false
|
||||
test --define blst_disabled=false
|
||||
run --define blst_disabled=false
|
||||
|
||||
build:kafka_enabled --define kafka_enabled=true
|
||||
build:kafka_enabled --define gotags=kafka_enabled
|
||||
|
||||
build:blst_enabled --define blst_enabled=true
|
||||
build:blst_enabled --define gotags=blst_enabled
|
||||
build:blst_disabled --define blst_disabled=true
|
||||
build:blst_disabled --define gotags=blst_disabled
|
||||
|
||||
# Release flags
|
||||
build:release --compilation_mode=opt
|
||||
@@ -84,7 +83,7 @@ build:fuzz --linkopt -Wl,--no-as-needed
|
||||
build:fuzz --define=gc_goopts=-d=libfuzzer,checkptr
|
||||
build:fuzz --run_under=//tools:fuzz_wrapper
|
||||
build:fuzz --compilation_mode=opt
|
||||
build:fuzz --define=blst_enabled=false
|
||||
build:fuzz --define=blst_disabled=true
|
||||
|
||||
test:fuzz --local_test_jobs="HOST_CPUS*.5"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# across machines, developers, and workspaces.
|
||||
#
|
||||
# This config is loaded from https://github.com/bazelbuild/bazel-toolchains/blob/master/bazelrc/latest.bazelrc
|
||||
build:remote-cache --remote_timeout=3600
|
||||
#build:remote-cache --remote_timeout=3600
|
||||
#build:remote-cache --spawn_strategy=standalone
|
||||
#build:remote-cache --strategy=Javac=standalone
|
||||
#build:remote-cache --strategy=Closure=standalone
|
||||
@@ -11,6 +11,13 @@ build:remote-cache --remote_timeout=3600
|
||||
# Prysm specific remote-cache properties.
|
||||
#build:remote-cache --disk_cache=
|
||||
build:remote-cache --remote_download_minimal
|
||||
build:remote-cache --remote_cache=grpc://bazel-remote-cache:9092
|
||||
build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092
|
||||
build:remote-cache --remote_local_fallback
|
||||
# Enforce stricter environment rules, which eliminates some non-hermetic
|
||||
# behavior and therefore improves both the remote cache hit rate and the
|
||||
# correctness and repeatability of the build.
|
||||
build:remote-cache --incompatible_strict_action_env=true
|
||||
|
||||
# Import workspace options.
|
||||
import %workspace%/.bazelrc
|
||||
|
||||
@@ -30,4 +30,4 @@ comment:
|
||||
|
||||
ignore:
|
||||
- "**/*.pb.go"
|
||||
- "**/*_mock.go"
|
||||
- "**/testing/**/*"
|
||||
|
||||
@@ -2,7 +2,8 @@ version = 1
|
||||
|
||||
exclude_patterns = [
|
||||
"tools/analyzers/**",
|
||||
"validator/keymanager/remote/keymanager_test.go"
|
||||
"validator/keymanager/remote/keymanager_test.go",
|
||||
"validator/web/site_data.go"
|
||||
]
|
||||
|
||||
[[analyzers]]
|
||||
|
||||
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
# Use blst tag to allow go and bazel builds for blst.
|
||||
run: go build -v --tags=blst_enabled ./...
|
||||
run: go build -v ./...
|
||||
|
||||
# Tests run via Bazel for now...
|
||||
# - name: Test
|
||||
|
||||
22
BUILD.bazel
22
BUILD.bazel
@@ -23,7 +23,16 @@ gazelle(
|
||||
# Protobuf compiler (non-gRPC)
|
||||
alias(
|
||||
name = "proto_compiler",
|
||||
actual = "@io_bazel_rules_go//proto:gogofast_proto",
|
||||
actual = "@io_bazel_rules_go//proto:go_proto",
|
||||
visibility = [
|
||||
"//proto:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
# Cast protobuf compiler (non-gRPC)
|
||||
alias(
|
||||
name = "cast_proto_compiler",
|
||||
actual = "@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast",
|
||||
visibility = [
|
||||
"//proto:__subpackages__",
|
||||
],
|
||||
@@ -32,21 +41,21 @@ alias(
|
||||
# Protobuf compiler (gRPC)
|
||||
alias(
|
||||
name = "grpc_proto_compiler",
|
||||
actual = "@io_bazel_rules_go//proto:gogofast_grpc",
|
||||
actual = "@io_bazel_rules_go//proto:go_grpc",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Protobuf gRPC compiler without gogoproto. Required for gRPC gateway.
|
||||
# Cast protobuf compiler (gRPC)
|
||||
alias(
|
||||
name = "grpc_nogogo_proto_compiler",
|
||||
actual = "@io_bazel_rules_go//proto:go_grpc",
|
||||
name = "cast_grpc_proto_compiler",
|
||||
actual = "@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast_grpc",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Protobuf gRPC gateway compiler
|
||||
alias(
|
||||
name = "grpc_gateway_proto_compiler",
|
||||
actual = "@com_github_grpc_ecosystem_grpc_gateway//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
|
||||
actual = "@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
@@ -111,6 +120,7 @@ nogo(
|
||||
"//tools/analyzers/shadowpredecl:go_tool_library",
|
||||
"//tools/analyzers/nop:go_tool_library",
|
||||
"//tools/analyzers/slicedirect:go_tool_library",
|
||||
"//tools/analyzers/interfacechecker:go_tool_library",
|
||||
"//tools/analyzers/ineffassign:go_tool_library",
|
||||
"//tools/analyzers/properpermissions:go_tool_library",
|
||||
] + select({
|
||||
|
||||
67
WORKSPACE
67
WORKSPACE
@@ -15,9 +15,9 @@ http_archive(
|
||||
|
||||
http_archive(
|
||||
name = "com_grail_bazel_toolchain",
|
||||
sha256 = "b924b102adc0c3368d38a19bd971cb4fa75362a27bc363d0084b90ca6877d3f0",
|
||||
strip_prefix = "bazel-toolchain-0.5.7",
|
||||
urls = ["https://github.com/grailbio/bazel-toolchain/archive/0.5.7.tar.gz"],
|
||||
sha256 = "040b9d00b8a03e8a28e38159ad0f2d0e0de625d93f453a9f226971a8c47e757b",
|
||||
strip_prefix = "bazel-toolchain-5f82830f9d6a1941c3eb29683c1864ccf2862454",
|
||||
urls = ["https://github.com/grailbio/bazel-toolchain/archive/5f82830f9d6a1941c3eb29683c1864ccf2862454.tar.gz"],
|
||||
)
|
||||
|
||||
load("@com_grail_bazel_toolchain//toolchain:deps.bzl", "bazel_toolchain_dependencies")
|
||||
@@ -76,9 +76,9 @@ http_archive(
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_docker",
|
||||
sha256 = "1286175a94c0b1335efe1d75d22ea06e89742557d3fac2a0366f242a6eac6f5a",
|
||||
strip_prefix = "rules_docker-ba4310833230294fa69b7d6ea1787ac684631a7d",
|
||||
urls = ["https://github.com/bazelbuild/rules_docker/archive/ba4310833230294fa69b7d6ea1787ac684631a7d.tar.gz"],
|
||||
sha256 = "59d5b42ac315e7eadffa944e86e90c2990110a1c8075f1cd145f487e999d22b3",
|
||||
strip_prefix = "rules_docker-0.17.0",
|
||||
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.17.0/rules_docker-v0.17.0.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@@ -156,7 +156,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(
|
||||
go_version = "1.16",
|
||||
go_version = "1.16.4",
|
||||
nogo = "@//:nogo",
|
||||
)
|
||||
|
||||
@@ -231,14 +231,14 @@ http_archive(
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.ssz_snappy",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "ef5396e4b13995da9776eeb5ae346a2de90970c28da3c4f0dcaa4ab9f0ad1f93",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/general.tar.gz",
|
||||
sha256 = "deacc076365c727d653ac064894ecf0d1b0a675d86704dc8de271259f6a7314b",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/general.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@@ -247,14 +247,14 @@ http_archive(
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.ssz_snappy",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "170551b441e7d54b73248372ad9ce8cb6c148810b5f1364637117a63f4f1c085",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/minimal.tar.gz",
|
||||
sha256 = "6e9886af3d2f024e563249d70388129e28e3e92f742f289238ed9b7ec7a7f930",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/minimal.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@@ -263,14 +263,14 @@ http_archive(
|
||||
filegroup(
|
||||
name = "test_data",
|
||||
srcs = glob([
|
||||
"**/*.ssz",
|
||||
"**/*.ssz_snappy",
|
||||
"**/*.yaml",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "b541a9979b4703fa5ee5d2182b0b5313c38efc54ae7eaec2eef793230a52ec83",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0/mainnet.tar.gz",
|
||||
sha256 = "a7b3d0ffc02a567250f424d69b2474fdc9477cd56eada60af7474560b46a8527",
|
||||
url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.1.0-alpha.3/mainnet.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@@ -286,9 +286,9 @@ buildifier_dependencies()
|
||||
|
||||
git_repository(
|
||||
name = "com_google_protobuf",
|
||||
commit = "fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a", # v3.13.0
|
||||
commit = "436bd7880e458532901c58f4d9d1ea23fa7edd52",
|
||||
remote = "https://github.com/protocolbuffers/protobuf",
|
||||
shallow_since = "1597443653 -0700",
|
||||
shallow_since = "1617835118 -0700",
|
||||
)
|
||||
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
@@ -331,33 +331,6 @@ http_archive(
|
||||
|
||||
# External dependencies
|
||||
|
||||
http_archive(
|
||||
name = "sszgen", # Hack because we don't want to build this binary with libfuzzer, but need it to build.
|
||||
build_file_content = """
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"sszgen/main.go",
|
||||
"sszgen/marshal.go",
|
||||
"sszgen/size.go",
|
||||
"sszgen/unmarshal.go",
|
||||
],
|
||||
importpath = "github.com/ferranbt/fastssz/sszgen",
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "sszgen",
|
||||
embed = [":go_default_library"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
strip_prefix = "fastssz-06015a5d84f9e4eefe2c21377ca678fa8f1a1b09",
|
||||
urls = ["https://github.com/ferranbt/fastssz/archive/06015a5d84f9e4eefe2c21377ca678fa8f1a1b09.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "prysm_web_ui",
|
||||
build_file_content = """
|
||||
@@ -367,9 +340,9 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "edb80f3a695d84f6000f0e05abf7a4bbf207c03abb91219780ec97e7d6ad21c8",
|
||||
sha256 = "54ce527b83d092da01127f2e3816f4d5cfbab69354caba8537f1ea55889b6d7c",
|
||||
urls = [
|
||||
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/v1.0.0-beta.3/prysm-web-ui.tar.gz",
|
||||
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/v1.0.0-beta.4/prysm-web-ui.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -42,14 +42,17 @@ go_library(
|
||||
"//beacon-chain/p2p:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/copyutil:go_default_library",
|
||||
"//shared/featureconfig:go_default_library",
|
||||
"//shared/interfaces:go_default_library",
|
||||
"//shared/mputil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/slotutil:go_default_library",
|
||||
@@ -60,7 +63,6 @@ go_library(
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
@@ -104,9 +106,11 @@ go_test(
|
||||
"//beacon-chain/db/testing:go_default_library",
|
||||
"//beacon-chain/p2p:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//beacon-chain/state/stateutil:go_default_library",
|
||||
"//proto/beacon/db:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
@@ -116,11 +120,10 @@ go_test(
|
||||
"@com_github_ethereum_go_ethereum//:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -156,6 +159,7 @@ go_test(
|
||||
"//beacon-chain/p2p:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
@@ -165,10 +169,9 @@ go_test(
|
||||
"@com_github_ethereum_go_ethereum//:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -5,13 +5,14 @@ import (
|
||||
"time"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
@@ -41,7 +42,7 @@ type GenesisFetcher interface {
|
||||
type HeadFetcher interface {
|
||||
HeadSlot() types.Slot
|
||||
HeadRoot(ctx context.Context) ([]byte, error)
|
||||
HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error)
|
||||
HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
|
||||
HeadState(ctx context.Context) (iface.BeaconState, error)
|
||||
HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error)
|
||||
HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error)
|
||||
@@ -76,7 +77,7 @@ func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
}
|
||||
|
||||
return stateV0.CopyCheckpoint(s.finalizedCheckpt)
|
||||
return copyutil.CopyCheckpoint(s.finalizedCheckpt)
|
||||
}
|
||||
|
||||
// CurrentJustifiedCheckpt returns the current justified checkpoint from head state.
|
||||
@@ -85,7 +86,7 @@ func (s *Service) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
}
|
||||
|
||||
return stateV0.CopyCheckpoint(s.justifiedCheckpt)
|
||||
return copyutil.CopyCheckpoint(s.justifiedCheckpt)
|
||||
}
|
||||
|
||||
// PreviousJustifiedCheckpt returns the previous justified checkpoint from head state.
|
||||
@@ -94,7 +95,7 @@ func (s *Service) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
}
|
||||
|
||||
return stateV0.CopyCheckpoint(s.prevJustifiedCheckpt)
|
||||
return copyutil.CopyCheckpoint(s.prevJustifiedCheckpt)
|
||||
}
|
||||
|
||||
// HeadSlot returns the slot of the head of the chain.
|
||||
@@ -123,11 +124,11 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if b == nil {
|
||||
if b == nil || b.IsNil() {
|
||||
return params.BeaconConfig().ZeroHash[:], nil
|
||||
}
|
||||
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
r, err := b.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -138,7 +139,7 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
|
||||
// HeadBlock returns the head block of the chain.
|
||||
// If the head is nil from service struct,
|
||||
// it will attempt to get the head block from DB.
|
||||
func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
|
||||
func (s *Service) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
|
||||
s.headLock.RLock()
|
||||
defer s.headLock.RUnlock()
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestHeadBlock_DataRace(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
s := &Service{
|
||||
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
|
||||
head: &head{block: ðpb.SignedBeaconBlock{}},
|
||||
head: &head{block: interfaces.WrappedPhase0SignedBeaconBlock(ðpb.SignedBeaconBlock{})},
|
||||
}
|
||||
go func() {
|
||||
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
|
||||
|
||||
@@ -5,19 +5,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Ensure Service implements chain info interface.
|
||||
@@ -125,7 +126,7 @@ func TestHeadRoot_UseDB(t *testing.T) {
|
||||
b := testutil.NewBeaconBlock()
|
||||
br, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), b))
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
require.NoError(t, beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: br[:]}))
|
||||
require.NoError(t, beaconDB.SaveHeadBlockRoot(context.Background(), br))
|
||||
r, err := c.HeadRoot(context.Background())
|
||||
@@ -139,11 +140,11 @@ func TestHeadBlock_CanRetrieve(t *testing.T) {
|
||||
s, err := stateV0.InitializeFromProto(&pb.BeaconState{})
|
||||
require.NoError(t, err)
|
||||
c := &Service{}
|
||||
c.head = &head{block: b, state: s}
|
||||
c.head = &head{block: interfaces.WrappedPhase0SignedBeaconBlock(b), state: s}
|
||||
|
||||
recevied, err := c.HeadBlock(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, b, recevied, "Incorrect head block received")
|
||||
assert.DeepEqual(t, b, recevied.Proto(), "Incorrect head block received")
|
||||
}
|
||||
|
||||
func TestHeadState_CanRetrieve(t *testing.T) {
|
||||
@@ -221,7 +222,7 @@ func TestIsCanonical_Ok(t *testing.T) {
|
||||
blk.Block.Slot = 0
|
||||
root, err := blk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, blk))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(blk)))
|
||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, root))
|
||||
can, err := c.IsCanonical(ctx, root)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -7,25 +7,26 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/slotutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// This defines the current chain service's view of head.
|
||||
type head struct {
|
||||
slot types.Slot // current head slot.
|
||||
root [32]byte // current head root.
|
||||
block *ethpb.SignedBeaconBlock // current head block.
|
||||
state iface.BeaconState // current head state.
|
||||
slot types.Slot // current head slot.
|
||||
root [32]byte // current head root.
|
||||
block interfaces.SignedBeaconBlock // current head block.
|
||||
state iface.BeaconState // current head state.
|
||||
}
|
||||
|
||||
// Determined the head from the fork choice service and saves its new data
|
||||
@@ -64,7 +65,7 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
|
||||
return err
|
||||
}
|
||||
s.cfg.ForkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
|
||||
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block, headStartRoot, f, j); err != nil {
|
||||
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block(), headStartRoot, f, j); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -104,7 +105,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newHeadBlock == nil || newHeadBlock.Block == nil {
|
||||
if newHeadBlock == nil || newHeadBlock.IsNil() || newHeadBlock.Block().IsNil() {
|
||||
return errors.New("cannot save nil head block")
|
||||
}
|
||||
|
||||
@@ -113,22 +114,32 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve head state in DB")
|
||||
}
|
||||
if newHeadState == nil {
|
||||
if newHeadState == nil || newHeadState.IsNil() {
|
||||
return errors.New("cannot save nil head state")
|
||||
}
|
||||
|
||||
// A chain re-org occurred, so we fire an event notifying the rest of the services.
|
||||
headSlot := s.HeadSlot()
|
||||
if bytesutil.ToBytes32(newHeadBlock.Block.ParentRoot) != bytesutil.ToBytes32(r) {
|
||||
newHeadSlot := newHeadBlock.Block().Slot()
|
||||
oldHeadRoot := s.headRoot()
|
||||
oldStateRoot := s.headBlock().Block().StateRoot()
|
||||
newStateRoot := newHeadBlock.Block().StateRoot()
|
||||
if bytesutil.ToBytes32(newHeadBlock.Block().ParentRoot()) != bytesutil.ToBytes32(r) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block.Slot),
|
||||
"newSlot": fmt.Sprintf("%d", newHeadSlot),
|
||||
"oldSlot": fmt.Sprintf("%d", headSlot),
|
||||
}).Debug("Chain reorg occurred")
|
||||
absoluteSlotDifference := slotutil.AbsoluteValueSlotDifference(newHeadSlot, headSlot)
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.Reorg,
|
||||
Data: &statefeed.ReorgData{
|
||||
NewSlot: newHeadBlock.Block.Slot,
|
||||
OldSlot: headSlot,
|
||||
Data: ðpbv1.EventChainReorg{
|
||||
Slot: newHeadSlot,
|
||||
Depth: absoluteSlotDifference,
|
||||
OldHeadBlock: oldHeadRoot[:],
|
||||
NewHeadBlock: headRoot[:],
|
||||
OldHeadState: oldStateRoot,
|
||||
NewHeadState: newStateRoot,
|
||||
Epoch: helpers.SlotToEpoch(newHeadSlot),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -143,13 +154,21 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
|
||||
return errors.Wrap(err, "could not save head root in DB")
|
||||
}
|
||||
|
||||
// Forward an event capturing a new chain head over a common event feed
|
||||
// done in a goroutine to avoid blocking the critical runtime main routine.
|
||||
go func() {
|
||||
if err := s.notifyNewHeadEvent(newHeadSlot, newHeadState, newStateRoot, headRoot[:]); err != nil {
|
||||
log.WithError(err).Error("Could not notify event feed of new chain head")
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// This gets called to update canonical root mapping. It does not save head block
|
||||
// root in DB. With the inception of initial-sync-cache-state flag, it uses finalized
|
||||
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
|
||||
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
|
||||
func (s *Service) saveHeadNoDB(ctx context.Context, b interfaces.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -161,20 +180,20 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
|
||||
return nil
|
||||
}
|
||||
|
||||
s.setHeadInitialSync(r, stateV0.CopySignedBeaconBlock(b), hs)
|
||||
s.setHeadInitialSync(r, b.Copy(), hs)
|
||||
return nil
|
||||
}
|
||||
|
||||
// This sets head view object which is used to track the head slot, root, block and state.
|
||||
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
|
||||
func (s *Service) setHead(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
|
||||
s.headLock.Lock()
|
||||
defer s.headLock.Unlock()
|
||||
|
||||
// This does a full copy of the block and state.
|
||||
s.head = &head{
|
||||
slot: block.Block.Slot,
|
||||
slot: block.Block().Slot(),
|
||||
root: root,
|
||||
block: stateV0.CopySignedBeaconBlock(block),
|
||||
block: block.Copy(),
|
||||
state: state.Copy(),
|
||||
}
|
||||
}
|
||||
@@ -182,15 +201,15 @@ func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state i
|
||||
// This sets head view object which is used to track the head slot, root, block and state. The method
|
||||
// assumes that state being passed into the method will not be modified by any other alternate
|
||||
// caller which holds the state's reference.
|
||||
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
|
||||
func (s *Service) setHeadInitialSync(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
|
||||
s.headLock.Lock()
|
||||
defer s.headLock.Unlock()
|
||||
|
||||
// This does a full copy of the block only.
|
||||
s.head = &head{
|
||||
slot: block.Block.Slot,
|
||||
slot: block.Block().Slot(),
|
||||
root: root,
|
||||
block: stateV0.CopySignedBeaconBlock(block),
|
||||
block: block.Copy(),
|
||||
state: state,
|
||||
}
|
||||
}
|
||||
@@ -215,8 +234,8 @@ func (s *Service) headRoot() [32]byte {
|
||||
// This returns the head block.
|
||||
// It does a full copy on head block for immutability.
|
||||
// This is a lock free version.
|
||||
func (s *Service) headBlock() *ethpb.SignedBeaconBlock {
|
||||
return stateV0.CopySignedBeaconBlock(s.head.block)
|
||||
func (s *Service) headBlock() interfaces.SignedBeaconBlock {
|
||||
return s.head.block.Copy()
|
||||
}
|
||||
|
||||
// This returns the head state.
|
||||
@@ -262,7 +281,7 @@ func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot
|
||||
return err
|
||||
}
|
||||
}
|
||||
if justifiedState == nil {
|
||||
if justifiedState == nil || justifiedState.IsNil() {
|
||||
return errors.New("justified state can't be nil")
|
||||
}
|
||||
|
||||
@@ -291,3 +310,53 @@ func (s *Service) getJustifiedBalances() []uint64 {
|
||||
defer s.justifiedBalancesLock.RUnlock()
|
||||
return s.justifiedBalances
|
||||
}
|
||||
|
||||
// Notifies a common event feed of a new chain head event. Called right after a new
|
||||
// chain head is determined, set, and saved to disk.
|
||||
func (s *Service) notifyNewHeadEvent(
|
||||
newHeadSlot types.Slot,
|
||||
newHeadState iface.BeaconState,
|
||||
newHeadStateRoot,
|
||||
newHeadRoot []byte,
|
||||
) error {
|
||||
previousDutyDependentRoot := s.genesisRoot[:]
|
||||
currentDutyDependentRoot := s.genesisRoot[:]
|
||||
|
||||
var previousDutyEpoch types.Epoch
|
||||
currentDutyEpoch := helpers.SlotToEpoch(newHeadSlot)
|
||||
if currentDutyEpoch > 0 {
|
||||
previousDutyEpoch = currentDutyEpoch.Sub(1)
|
||||
}
|
||||
currentDutySlot, err := helpers.StartSlot(currentDutyEpoch)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get duty slot")
|
||||
}
|
||||
previousDutySlot, err := helpers.StartSlot(previousDutyEpoch)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get duty slot")
|
||||
}
|
||||
if currentDutySlot > 0 {
|
||||
currentDutyDependentRoot, err = helpers.BlockRootAtSlot(newHeadState, currentDutySlot-1)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get duty dependent root")
|
||||
}
|
||||
}
|
||||
if previousDutySlot > 0 {
|
||||
previousDutyDependentRoot, err = helpers.BlockRootAtSlot(newHeadState, previousDutySlot-1)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get duty dependent root")
|
||||
}
|
||||
}
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.NewHead,
|
||||
Data: ðpbv1.EventHead{
|
||||
Slot: newHeadSlot,
|
||||
Block: newHeadRoot,
|
||||
State: newHeadStateRoot,
|
||||
EpochTransition: helpers.IsEpochEnd(newHeadSlot),
|
||||
PreviousDutyDependentRoot: previousDutyDependentRoot,
|
||||
CurrentDutyDependentRoot: currentDutyDependentRoot,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
@@ -33,13 +37,24 @@ func TestSaveHead_Different(t *testing.T) {
|
||||
service := setupBeaconChain(t, beaconDB)
|
||||
|
||||
oldRoot := [32]byte{'A'}
|
||||
service.head = &head{slot: 0, root: oldRoot}
|
||||
service.head = &head{
|
||||
slot: 0,
|
||||
root: oldRoot,
|
||||
block: interfaces.WrappedPhase0SignedBeaconBlock(
|
||||
ðpb.SignedBeaconBlock{
|
||||
Block: ðpb.BeaconBlock{
|
||||
Slot: 0,
|
||||
StateRoot: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
newHeadSignedBlock := testutil.NewBeaconBlock()
|
||||
newHeadSignedBlock.Block.Slot = 1
|
||||
newHeadBlock := newHeadSignedBlock.Block
|
||||
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(newHeadSignedBlock)))
|
||||
newRoot, err := newHeadBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
headState, err := testutil.NewBeaconState()
|
||||
@@ -54,7 +69,7 @@ func TestSaveHead_Different(t *testing.T) {
|
||||
cachedRoot, err := service.HeadRoot(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, cachedRoot, newRoot[:], "Head did not change")
|
||||
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
|
||||
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
|
||||
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
|
||||
}
|
||||
|
||||
@@ -65,7 +80,18 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
|
||||
service := setupBeaconChain(t, beaconDB)
|
||||
|
||||
oldRoot := [32]byte{'A'}
|
||||
service.head = &head{slot: 0, root: oldRoot}
|
||||
service.head = &head{
|
||||
slot: 0,
|
||||
root: oldRoot,
|
||||
block: interfaces.WrappedPhase0SignedBeaconBlock(
|
||||
ðpb.SignedBeaconBlock{
|
||||
Block: ðpb.BeaconBlock{
|
||||
Slot: 0,
|
||||
StateRoot: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
reorgChainParent := [32]byte{'B'}
|
||||
newHeadSignedBlock := testutil.NewBeaconBlock()
|
||||
@@ -73,7 +99,7 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
|
||||
newHeadSignedBlock.Block.ParentRoot = reorgChainParent[:]
|
||||
newHeadBlock := newHeadSignedBlock.Block
|
||||
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(newHeadSignedBlock)))
|
||||
newRoot, err := newHeadBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
headState, err := testutil.NewBeaconState()
|
||||
@@ -90,7 +116,7 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
|
||||
if !bytes.Equal(cachedRoot, newRoot[:]) {
|
||||
t.Error("Head did not change")
|
||||
}
|
||||
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
|
||||
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
|
||||
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
|
||||
require.LogsContain(t, hook, "Chain reorg occurred")
|
||||
}
|
||||
@@ -112,7 +138,7 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
|
||||
service := setupBeaconChain(t, beaconDB)
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), b))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -122,3 +148,69 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.updateHead(context.Background(), []uint64{}))
|
||||
}
|
||||
|
||||
func Test_notifyNewHeadEvent(t *testing.T) {
|
||||
t.Run("genesis_state_root", func(t *testing.T) {
|
||||
bState, _ := testutil.DeterministicGenesisState(t, 10)
|
||||
notifier := &mock.MockStateNotifier{RecordEvents: true}
|
||||
srv := &Service{
|
||||
cfg: &Config{
|
||||
StateNotifier: notifier,
|
||||
},
|
||||
genesisRoot: [32]byte{1},
|
||||
}
|
||||
newHeadStateRoot := [32]byte{2}
|
||||
newHeadRoot := [32]byte{3}
|
||||
err := srv.notifyNewHeadEvent(1, bState, newHeadStateRoot[:], newHeadRoot[:])
|
||||
require.NoError(t, err)
|
||||
events := notifier.ReceivedEvents()
|
||||
require.Equal(t, 1, len(events))
|
||||
|
||||
eventHead, ok := events[0].Data.(*ethpbv1.EventHead)
|
||||
require.Equal(t, true, ok)
|
||||
wanted := ðpbv1.EventHead{
|
||||
Slot: 1,
|
||||
Block: newHeadRoot[:],
|
||||
State: newHeadStateRoot[:],
|
||||
EpochTransition: false,
|
||||
PreviousDutyDependentRoot: srv.genesisRoot[:],
|
||||
CurrentDutyDependentRoot: srv.genesisRoot[:],
|
||||
}
|
||||
require.DeepSSZEqual(t, wanted, eventHead)
|
||||
})
|
||||
t.Run("non_genesis_values", func(t *testing.T) {
|
||||
bState, _ := testutil.DeterministicGenesisState(t, 10)
|
||||
notifier := &mock.MockStateNotifier{RecordEvents: true}
|
||||
genesisRoot := [32]byte{1}
|
||||
srv := &Service{
|
||||
cfg: &Config{
|
||||
StateNotifier: notifier,
|
||||
},
|
||||
genesisRoot: genesisRoot,
|
||||
}
|
||||
epoch1Start, err := helpers.StartSlot(1)
|
||||
require.NoError(t, err)
|
||||
epoch2Start, err := helpers.StartSlot(1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, bState.SetSlot(epoch1Start))
|
||||
|
||||
newHeadStateRoot := [32]byte{2}
|
||||
newHeadRoot := [32]byte{3}
|
||||
err = srv.notifyNewHeadEvent(epoch2Start, bState, newHeadStateRoot[:], newHeadRoot[:])
|
||||
require.NoError(t, err)
|
||||
events := notifier.ReceivedEvents()
|
||||
require.Equal(t, 1, len(events))
|
||||
|
||||
eventHead, ok := events[0].Data.(*ethpbv1.EventHead)
|
||||
require.Equal(t, true, ok)
|
||||
wanted := ðpbv1.EventHead{
|
||||
Slot: epoch2Start,
|
||||
Block: newHeadRoot[:],
|
||||
State: newHeadStateRoot[:],
|
||||
EpochTransition: false,
|
||||
PreviousDutyDependentRoot: genesisRoot[:],
|
||||
CurrentDutyDependentRoot: make([]byte, 32),
|
||||
}
|
||||
require.DeepSSZEqual(t, wanted, eventHead)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.WithError(err).Error("Could not get head state")
|
||||
return
|
||||
}
|
||||
if headState == nil {
|
||||
if headState == nil || headState.IsNil() {
|
||||
if _, err := w.Write([]byte("Unavailable during initial syncing")); err != nil {
|
||||
log.WithError(err).Error("Failed to render p2p info page")
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -37,7 +38,7 @@ func TestService_TreeHandler(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, [32]byte{'a'}, [32]byte{'g'}, [32]byte{'c'}, 0, 0))
|
||||
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 1, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'c'}, 0, 0))
|
||||
s.setHead([32]byte{'a'}, testutil.NewBeaconBlock(), headState)
|
||||
s.setHead([32]byte{'a'}, interfaces.WrappedPhase0SignedBeaconBlock(testutil.NewBeaconBlock()), headState)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(s.TreeHandler)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
)
|
||||
|
||||
// This saves a beacon block to the initial sync blocks cache.
|
||||
func (s *Service) saveInitSyncBlock(r [32]byte, b *ethpb.SignedBeaconBlock) {
|
||||
func (s *Service) saveInitSyncBlock(r [32]byte, b interfaces.SignedBeaconBlock) {
|
||||
s.initSyncBlocksLock.Lock()
|
||||
defer s.initSyncBlocksLock.Unlock()
|
||||
s.initSyncBlocks[r] = b
|
||||
@@ -22,7 +22,7 @@ func (s *Service) hasInitSyncBlock(r [32]byte) bool {
|
||||
|
||||
// This retrieves a beacon block from the initial sync blocks cache using the root of
|
||||
// the block.
|
||||
func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
|
||||
func (s *Service) getInitSyncBlock(r [32]byte) interfaces.SignedBeaconBlock {
|
||||
s.initSyncBlocksLock.RLock()
|
||||
defer s.initSyncBlocksLock.RUnlock()
|
||||
b := s.initSyncBlocks[r]
|
||||
@@ -31,11 +31,11 @@ func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
|
||||
|
||||
// This retrieves all the beacon blocks from the initial sync blocks cache, the returned
|
||||
// blocks are unordered.
|
||||
func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
|
||||
func (s *Service) getInitSyncBlocks() []interfaces.SignedBeaconBlock {
|
||||
s.initSyncBlocksLock.RLock()
|
||||
defer s.initSyncBlocksLock.RUnlock()
|
||||
|
||||
blks := make([]*ethpb.SignedBeaconBlock, 0, len(s.initSyncBlocks))
|
||||
blks := make([]interfaces.SignedBeaconBlock, 0, len(s.initSyncBlocks))
|
||||
for _, b := range s.initSyncBlocks {
|
||||
blks = append(blks, b)
|
||||
}
|
||||
@@ -46,5 +46,5 @@ func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
|
||||
func (s *Service) clearInitSyncBlocks() {
|
||||
s.initSyncBlocksLock.Lock()
|
||||
defer s.initSyncBlocksLock.Unlock()
|
||||
s.initSyncBlocks = make(map[[32]byte]*ethpb.SignedBeaconBlock)
|
||||
s.initSyncBlocks = make(map[[32]byte]interfaces.SignedBeaconBlock)
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/timeutils"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -15,36 +16,36 @@ import (
|
||||
var log = logrus.WithField("prefix", "blockchain")
|
||||
|
||||
// logs state transition related data every slot.
|
||||
func logStateTransitionData(b *ethpb.BeaconBlock) {
|
||||
func logStateTransitionData(b interfaces.BeaconBlock) {
|
||||
log := log.WithField("slot", b.Slot)
|
||||
if len(b.Body.Attestations) > 0 {
|
||||
log = log.WithField("attestations", len(b.Body.Attestations))
|
||||
if len(b.Body().Attestations()) > 0 {
|
||||
log = log.WithField("attestations", len(b.Body().Attestations()))
|
||||
}
|
||||
if len(b.Body.Deposits) > 0 {
|
||||
log = log.WithField("deposits", len(b.Body.Deposits))
|
||||
if len(b.Body().Deposits()) > 0 {
|
||||
log = log.WithField("deposits", len(b.Body().Deposits()))
|
||||
}
|
||||
if len(b.Body.AttesterSlashings) > 0 {
|
||||
log = log.WithField("attesterSlashings", len(b.Body.AttesterSlashings))
|
||||
if len(b.Body().AttesterSlashings()) > 0 {
|
||||
log = log.WithField("attesterSlashings", len(b.Body().AttesterSlashings()))
|
||||
}
|
||||
if len(b.Body.ProposerSlashings) > 0 {
|
||||
log = log.WithField("proposerSlashings", len(b.Body.ProposerSlashings))
|
||||
if len(b.Body().ProposerSlashings()) > 0 {
|
||||
log = log.WithField("proposerSlashings", len(b.Body().ProposerSlashings()))
|
||||
}
|
||||
if len(b.Body.VoluntaryExits) > 0 {
|
||||
log = log.WithField("voluntaryExits", len(b.Body.VoluntaryExits))
|
||||
if len(b.Body().VoluntaryExits()) > 0 {
|
||||
log = log.WithField("voluntaryExits", len(b.Body().VoluntaryExits()))
|
||||
}
|
||||
log.Info("Finished applying state transition")
|
||||
}
|
||||
|
||||
func logBlockSyncStatus(block *ethpb.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
|
||||
startTime, err := helpers.SlotToTime(genesisTime, block.Slot)
|
||||
func logBlockSyncStatus(block interfaces.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
|
||||
startTime, err := helpers.SlotToTime(genesisTime, block.Slot())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": block.Slot,
|
||||
"slotInEpoch": block.Slot % params.BeaconConfig().SlotsPerEpoch,
|
||||
"slot": block.Slot(),
|
||||
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
|
||||
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
|
||||
"epoch": helpers.SlotToEpoch(block.Slot),
|
||||
"epoch": helpers.SlotToEpoch(block.Slot()),
|
||||
"finalizedEpoch": finalized.Epoch,
|
||||
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
|
||||
}).Info("Synced new block")
|
||||
|
||||
@@ -3,7 +3,8 @@ package blockchain
|
||||
import (
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
@@ -56,7 +57,7 @@ func Test_logStateTransitionData(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
hook := logTest.NewGlobal()
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
logStateTransitionData(tt.b)
|
||||
logStateTransitionData(interfaces.WrappedPhase0BeaconBlock(tt.b))
|
||||
require.LogsContain(t, hook, tt.want)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -227,8 +228,8 @@ func reportEpochMetrics(ctx context.Context, postState, headState iface.BeaconSt
|
||||
return nil
|
||||
}
|
||||
|
||||
func reportAttestationInclusion(blk *ethpb.BeaconBlock) {
|
||||
for _, att := range blk.Body.Attestations {
|
||||
attestationInclusionDelay.Observe(float64(blk.Slot - att.Data.Slot))
|
||||
func reportAttestationInclusion(blk interfaces.BeaconBlock) {
|
||||
for _, att := range blk.Body().Attestations() {
|
||||
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/timeutils"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -46,7 +46,7 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) error
|
||||
if err := helpers.ValidateSlotTargetEpoch(a.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
tgt := stateV0.CopyCheckpoint(a.Data.Target)
|
||||
tgt := copyutil.CopyCheckpoint(a.Data.Target)
|
||||
|
||||
// Note that target root check is ignored here because it was performed in sync's validation pipeline:
|
||||
// validate_aggregate_proof.go and validate_beacon_attestation.go
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/mputil"
|
||||
@@ -29,7 +29,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (ifac
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get cached checkpoint state")
|
||||
}
|
||||
if cachedState != nil {
|
||||
if cachedState != nil && !cachedState.IsNil() {
|
||||
return cachedState, nil
|
||||
}
|
||||
|
||||
@@ -99,14 +99,14 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
|
||||
}
|
||||
// If the block does not exist in db, check again if block exists in initial sync block cache.
|
||||
// This could happen as the node first syncs to head.
|
||||
if b == nil && s.hasInitSyncBlock(r) {
|
||||
if (b == nil || b.IsNil()) && s.hasInitSyncBlock(r) {
|
||||
b = s.getInitSyncBlock(r)
|
||||
}
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return err
|
||||
}
|
||||
if b.Block.Slot > data.Slot {
|
||||
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block.Slot, data.Slot)
|
||||
if b.Block().Slot() > data.Slot {
|
||||
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block().Slot(), data.Slot)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -37,13 +38,13 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
|
||||
|
||||
BlkWithOutState := testutil.NewBeaconBlock()
|
||||
BlkWithOutState.Block.Slot = 0
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithOutState))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(BlkWithOutState)))
|
||||
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
BlkWithStateBadAtt := testutil.NewBeaconBlock()
|
||||
BlkWithStateBadAtt.Block.Slot = 1
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithStateBadAtt))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(BlkWithStateBadAtt)))
|
||||
BlkWithStateBadAttRoot, err := BlkWithStateBadAtt.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -54,7 +55,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
|
||||
|
||||
BlkWithValidState := testutil.NewBeaconBlock()
|
||||
BlkWithValidState.Block.Slot = 2
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithValidState))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(BlkWithValidState)))
|
||||
|
||||
BlkWithValidStateRoot, err := BlkWithValidState.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
@@ -321,7 +322,7 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
b.Block.Slot = 2
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
d := ðpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
|
||||
@@ -339,7 +340,7 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
b.Block.Slot = 2
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
d := ðpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
|
||||
@@ -357,7 +358,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
|
||||
|
||||
b32 := testutil.NewBeaconBlock()
|
||||
b32.Block.Slot = 32
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b32)))
|
||||
r32, err := b32.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -366,7 +367,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
|
||||
b33 := testutil.NewBeaconBlock()
|
||||
b33.Block.Slot = 33
|
||||
b33.Block.ParentRoot = r32[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b33)))
|
||||
r33, err := b33.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -384,7 +385,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
|
||||
|
||||
b32 := testutil.NewBeaconBlock()
|
||||
b32.Block.Slot = 32
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b32)))
|
||||
r32, err := b32.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -393,7 +394,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
|
||||
b33 := testutil.NewBeaconBlock()
|
||||
b33.Block.Slot = 33
|
||||
b33.Block.ParentRoot = r32[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b33)))
|
||||
r33, err := b33.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -6,17 +6,19 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
@@ -51,7 +53,8 @@ var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
|
||||
// assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root
|
||||
//
|
||||
// # Check the block is valid and compute the post-state
|
||||
// state = state_transition(pre_state, signed_block, True)
|
||||
// state = pre_state.copy()
|
||||
// state_transition(state, signed_block, True)
|
||||
// # Add new block to the store
|
||||
// store.blocks[hash_tree_root(block)] = block
|
||||
// # Add new state for this block to the store
|
||||
@@ -80,30 +83,23 @@ var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
|
||||
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
|
||||
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
|
||||
// store.justified_checkpoint = state.current_justified_checkpoint
|
||||
func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||
func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
|
||||
defer span.End()
|
||||
|
||||
if signed == nil || signed.Block == nil {
|
||||
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
|
||||
return errors.New("nil block")
|
||||
}
|
||||
b := signed.Block
|
||||
b := signed.Block()
|
||||
|
||||
preState, err := s.getBlockPreState(ctx, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
set, postState, err := state.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, signed)
|
||||
postState, err := state.ExecuteStateTransition(ctx, preState, signed)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not execute state transition")
|
||||
}
|
||||
valid, err := set.Verify()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not batch verify signature")
|
||||
}
|
||||
if !valid {
|
||||
return errors.New("signature in block failed to verify")
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.savePostStateInfo(ctx, blockRoot, signed, postState, false /* reg sync */); err != nil {
|
||||
@@ -149,7 +145,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.BlockProcessed,
|
||||
Data: &statefeed.BlockProcessedData{
|
||||
Slot: signed.Block.Slot,
|
||||
Slot: signed.Block().Slot(),
|
||||
BlockRoot: blockRoot,
|
||||
SignedBlock: signed,
|
||||
Verified: true,
|
||||
@@ -172,6 +168,16 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
// Send an event regarding the new finalized checkpoint over a common event feed.
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.FinalizedCheckpoint,
|
||||
Data: ðpbv1.EventFinalizedCheckpoint{
|
||||
Epoch: postState.FinalizedCheckpoint().Epoch,
|
||||
Block: postState.FinalizedCheckpoint().Root,
|
||||
State: signed.Block().StateRoot(),
|
||||
},
|
||||
})
|
||||
|
||||
// Use a custom deadline here, since this method runs asynchronously.
|
||||
// We ignore the parent method's context and instead create a new one
|
||||
// with a custom deadline, therefore using the background context instead.
|
||||
@@ -181,6 +187,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
|
||||
log.WithError(err).Error("Could not insert finalized deposits.")
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
defer reportAttestationInclusion(b)
|
||||
@@ -188,7 +195,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
|
||||
return s.handleEpochBoundary(ctx, postState)
|
||||
}
|
||||
|
||||
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
|
||||
func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock,
|
||||
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
|
||||
defer span.End()
|
||||
@@ -196,21 +203,21 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
|
||||
if len(blks) == 0 || len(blockRoots) == 0 {
|
||||
return nil, nil, errors.New("no blocks provided")
|
||||
}
|
||||
if blks[0] == nil || blks[0].Block == nil {
|
||||
if blks[0] == nil || blks[0].IsNil() || blks[0].Block().IsNil() {
|
||||
return nil, nil, errors.New("nil block")
|
||||
}
|
||||
b := blks[0].Block
|
||||
b := blks[0].Block()
|
||||
|
||||
// Retrieve incoming block's pre state.
|
||||
if err := s.verifyBlkPreState(ctx, b); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
|
||||
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot()))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if preState == nil {
|
||||
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot)
|
||||
if preState == nil || preState.IsNil() {
|
||||
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot())
|
||||
}
|
||||
|
||||
jCheckpoints := make([]*ethpb.Checkpoint, len(blks))
|
||||
@@ -264,16 +271,16 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
|
||||
|
||||
// handles a block after the block's batch has been verified, where we can save blocks
|
||||
// their state summaries and split them off to relative hot/cold storage.
|
||||
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb.SignedBeaconBlock,
|
||||
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interfaces.SignedBeaconBlock,
|
||||
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||
b := signed.Block
|
||||
b := signed.Block()
|
||||
|
||||
s.saveInitSyncBlock(blockRoot, signed)
|
||||
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, fCheckpoint, jCheckpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{
|
||||
Slot: signed.Block.Slot,
|
||||
Slot: signed.Block().Slot(),
|
||||
Root: blockRoot[:],
|
||||
}); err != nil {
|
||||
return err
|
||||
@@ -342,7 +349,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState iface.Beaco
|
||||
|
||||
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
|
||||
// to gain information on the most current chain.
|
||||
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte,
|
||||
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock, root [32]byte,
|
||||
st iface.BeaconState) error {
|
||||
fCheckpoint := st.FinalizedCheckpoint()
|
||||
jCheckpoint := st.CurrentJustifiedCheckpoint()
|
||||
@@ -350,7 +357,7 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
|
||||
return err
|
||||
}
|
||||
// Feed in block's attestations to fork choice store.
|
||||
for _, a := range blk.Body.Attestations {
|
||||
for _, a := range blk.Body().Attestations() {
|
||||
committee, err := helpers.BeaconCommitteeFromState(st, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -364,14 +371,14 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock,
|
||||
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock,
|
||||
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
// Feed in block to fork choice store.
|
||||
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
|
||||
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
|
||||
blk.Slot(), root, bytesutil.ToBytes32(blk.ParentRoot()), bytesutil.ToBytes32(blk.Body().Graffiti()),
|
||||
jCheckpoint.Epoch,
|
||||
fCheckpoint.Epoch); err != nil {
|
||||
return errors.Wrap(err, "could not process block for proto array fork choice")
|
||||
@@ -381,19 +388,19 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
|
||||
|
||||
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
|
||||
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
|
||||
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
|
||||
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
|
||||
defer span.End()
|
||||
if initSync {
|
||||
s.saveInitSyncBlock(r, b)
|
||||
} else if err := s.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 {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/traceutil"
|
||||
"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
|
||||
// to retrieve the state in DB. It verifies the pre state's validity and the incoming block
|
||||
// is in the correct time window.
|
||||
func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (iface.BeaconState, error) {
|
||||
func (s *Service) getBlockPreState(ctx context.Context, b interfaces.BeaconBlock) (iface.BeaconState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
|
||||
defer span.End()
|
||||
|
||||
@@ -35,16 +36,16 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (i
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
|
||||
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
|
||||
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot())
|
||||
}
|
||||
if preState == nil {
|
||||
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot)
|
||||
if preState == nil || preState.IsNil() {
|
||||
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot())
|
||||
}
|
||||
|
||||
// Verify block slot time is not from the future.
|
||||
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -57,11 +58,11 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (i
|
||||
}
|
||||
|
||||
// verifyBlkPreState validates input block has a valid pre-state.
|
||||
func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) error {
|
||||
func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBlock) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
|
||||
defer span.End()
|
||||
|
||||
parentRoot := bytesutil.ToBytes32(b.ParentRoot)
|
||||
parentRoot := bytesutil.ToBytes32(b.ParentRoot())
|
||||
// Loosen the check to HasBlock because state summary gets saved in batches
|
||||
// during initial syncing. There's no risk given a state summary object is just a
|
||||
// a subset of the block object.
|
||||
@@ -69,7 +70,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
|
||||
return errors.New("could not reconstruct parent state")
|
||||
}
|
||||
|
||||
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot)); err != nil {
|
||||
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot())); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -96,11 +97,11 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if finalizedBlkSigned == nil || finalizedBlkSigned.Block == nil {
|
||||
if finalizedBlkSigned == nil || finalizedBlkSigned.IsNil() || finalizedBlkSigned.Block().IsNil() {
|
||||
return errors.New("nil finalized block")
|
||||
}
|
||||
finalizedBlk := finalizedBlkSigned.Block
|
||||
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot)
|
||||
finalizedBlk := finalizedBlkSigned.Block()
|
||||
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized block root")
|
||||
}
|
||||
@@ -110,7 +111,7 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
|
||||
|
||||
if !bytes.Equal(bFinalizedRoot, fRoot[:]) {
|
||||
err := fmt.Errorf("block %#x is not a descendent of the current finalized block slot %d, %#x != %#x",
|
||||
bytesutil.Trunc(root[:]), finalizedBlk.Slot, bytesutil.Trunc(bFinalizedRoot),
|
||||
bytesutil.Trunc(root[:]), finalizedBlk.Slot(), bytesutil.Trunc(bFinalizedRoot),
|
||||
bytesutil.Trunc(fRoot[:]))
|
||||
traceutil.AnnotateError(span, err)
|
||||
return err
|
||||
@@ -120,13 +121,13 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
|
||||
|
||||
// verifyBlkFinalizedSlot validates input block is not less than or equal
|
||||
// to current finalized slot.
|
||||
func (s *Service) verifyBlkFinalizedSlot(b *ethpb.BeaconBlock) error {
|
||||
func (s *Service) verifyBlkFinalizedSlot(b interfaces.BeaconBlock) error {
|
||||
finalizedSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if finalizedSlot >= b.Slot {
|
||||
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot, finalizedSlot)
|
||||
if finalizedSlot >= b.Slot() {
|
||||
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot(), finalizedSlot)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -139,7 +140,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
|
||||
if helpers.SlotsSinceEpochStarts(s.CurrentSlot()) < params.BeaconConfig().SafeSlotsToUpdateJustified {
|
||||
return true, nil
|
||||
}
|
||||
var newJustifiedBlockSigned *ethpb.SignedBeaconBlock
|
||||
var newJustifiedBlockSigned interfaces.SignedBeaconBlock
|
||||
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(newJustifiedCheckpt.Root))
|
||||
var err error
|
||||
if s.hasInitSyncBlock(justifiedRoot) {
|
||||
@@ -150,19 +151,19 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.Block == nil {
|
||||
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.IsNil() || newJustifiedBlockSigned.Block().IsNil() {
|
||||
return false, errors.New("nil new justified block")
|
||||
}
|
||||
|
||||
newJustifiedBlock := newJustifiedBlockSigned.Block
|
||||
newJustifiedBlock := newJustifiedBlockSigned.Block()
|
||||
jSlot, err := helpers.StartSlot(s.justifiedCheckpt.Epoch)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if newJustifiedBlock.Slot <= jSlot {
|
||||
if newJustifiedBlock.Slot() <= jSlot {
|
||||
return false, nil
|
||||
}
|
||||
var justifiedBlockSigned *ethpb.SignedBeaconBlock
|
||||
var justifiedBlockSigned interfaces.SignedBeaconBlock
|
||||
cachedJustifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))
|
||||
if s.hasInitSyncBlock(cachedJustifiedRoot) {
|
||||
justifiedBlockSigned = s.getInitSyncBlock(cachedJustifiedRoot)
|
||||
@@ -173,11 +174,11 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
|
||||
}
|
||||
}
|
||||
|
||||
if justifiedBlockSigned == nil || justifiedBlockSigned.Block == nil {
|
||||
if justifiedBlockSigned == nil || justifiedBlockSigned.IsNil() || justifiedBlockSigned.Block().IsNil() {
|
||||
return false, errors.New("nil justified block")
|
||||
}
|
||||
justifiedBlock := justifiedBlockSigned.Block
|
||||
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot)
|
||||
justifiedBlock := justifiedBlockSigned.Block()
|
||||
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -307,15 +308,15 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot)
|
||||
signed = s.getInitSyncBlock(r)
|
||||
}
|
||||
|
||||
if signed == nil || signed.Block == nil {
|
||||
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
|
||||
return nil, errors.New("nil block")
|
||||
}
|
||||
b := signed.Block
|
||||
if b.Slot == slot || b.Slot < slot {
|
||||
b := signed.Block()
|
||||
if b.Slot() == slot || b.Slot() < slot {
|
||||
return r[:], nil
|
||||
}
|
||||
|
||||
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot), slot)
|
||||
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot()), slot)
|
||||
}
|
||||
|
||||
// This updates justified check point in store, if the new justified is later than stored justified or
|
||||
@@ -363,13 +364,13 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state iface.
|
||||
|
||||
// This retrieves missing blocks from DB (ie. the blocks that couldn't be received over sync) and inserts them to fork choice store.
|
||||
// This is useful for block tree visualizer and additional vote accounting.
|
||||
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.BeaconBlock,
|
||||
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk interfaces.BeaconBlock,
|
||||
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
|
||||
pendingNodes := make([]*ethpb.BeaconBlock, 0)
|
||||
pendingNodes := make([]interfaces.BeaconBlock, 0)
|
||||
pendingRoots := make([][32]byte, 0)
|
||||
|
||||
parentRoot := bytesutil.ToBytes32(blk.ParentRoot)
|
||||
slot := blk.Slot
|
||||
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
|
||||
slot := blk.Slot()
|
||||
// Fork choice only matters from last finalized slot.
|
||||
fSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
|
||||
if err != nil {
|
||||
@@ -383,11 +384,11 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
|
||||
return err
|
||||
}
|
||||
|
||||
pendingNodes = append(pendingNodes, b.Block)
|
||||
pendingNodes = append(pendingNodes, b.Block())
|
||||
copiedRoot := parentRoot
|
||||
pendingRoots = append(pendingRoots, copiedRoot)
|
||||
parentRoot = bytesutil.ToBytes32(b.Block.ParentRoot)
|
||||
slot = b.Block.Slot
|
||||
parentRoot = bytesutil.ToBytes32(b.Block().ParentRoot())
|
||||
slot = b.Block().Slot()
|
||||
higherThanFinalized = slot > fSlot
|
||||
}
|
||||
|
||||
@@ -397,7 +398,7 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
|
||||
b := pendingNodes[i]
|
||||
r := pendingRoots[i]
|
||||
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
|
||||
b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti),
|
||||
b.Slot(), r, bytesutil.ToBytes32(b.ParentRoot()), bytesutil.ToBytes32(b.Body().Graffiti()),
|
||||
jCheckpoint.Epoch,
|
||||
fCheckpoint.Epoch); err != nil {
|
||||
return errors.Wrap(err, "could not process block for proto array fork choice")
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
@@ -21,8 +21,10 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -43,7 +45,7 @@ func TestStore_OnBlock(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
validGenesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
st, err := testutil.NewBeaconState()
|
||||
@@ -54,7 +56,7 @@ func TestStore_OnBlock(t *testing.T) {
|
||||
random := testutil.NewBeaconBlock()
|
||||
random.Block.Slot = 1
|
||||
random.Block.ParentRoot = validGenesisRoot[:]
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, random))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(random)))
|
||||
randomParentRoot, err := random.Block.HashTreeRoot()
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
|
||||
@@ -120,7 +122,7 @@ func TestStore_OnBlock(t *testing.T) {
|
||||
|
||||
root, err := tt.blk.Block.HashTreeRoot()
|
||||
assert.NoError(t, err)
|
||||
err = service.onBlock(ctx, tt.blk, root)
|
||||
err = service.onBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(tt.blk), root)
|
||||
assert.ErrorContains(t, tt.wantErrString, err)
|
||||
})
|
||||
}
|
||||
@@ -139,38 +141,40 @@ func TestStore_OnBlockBatch(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
gRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{
|
||||
Root: gRoot[:],
|
||||
}
|
||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||
service.saveInitSyncBlock(gRoot, genesis)
|
||||
service.saveInitSyncBlock(gRoot, interfaces.WrappedPhase0SignedBeaconBlock(genesis))
|
||||
|
||||
st, keys := testutil.DeterministicGenesisState(t, 64)
|
||||
|
||||
bState := st.Copy()
|
||||
|
||||
var blks []*ethpb.SignedBeaconBlock
|
||||
var blks []interfaces.SignedBeaconBlock
|
||||
var blkRoots [][32]byte
|
||||
var firstState iface.BeaconState
|
||||
for i := 1; i < 10; i++ {
|
||||
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), types.Slot(i))
|
||||
require.NoError(t, err)
|
||||
bState, err = state.ExecuteStateTransition(ctx, bState, b)
|
||||
bState, err = state.ExecuteStateTransition(ctx, bState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
require.NoError(t, err)
|
||||
if i == 1 {
|
||||
firstState = bState.Copy()
|
||||
}
|
||||
root, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.saveInitSyncBlock(root, b)
|
||||
blks = append(blks, b)
|
||||
service.saveInitSyncBlock(root, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
blks = append(blks, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
blkRoots = append(blkRoots, root)
|
||||
}
|
||||
|
||||
blks[0].Block.ParentRoot = gRoot[:]
|
||||
rBlock, err := blks[0].PbPhase0Block()
|
||||
assert.NoError(t, err)
|
||||
rBlock.Block.ParentRoot = gRoot[:]
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), blks[0]))
|
||||
require.NoError(t, service.cfg.StateGen.SaveState(ctx, blkRoots[0], firstState))
|
||||
_, _, err = service.onBlockBatch(ctx, blks[1:], blkRoots[1:])
|
||||
@@ -200,8 +204,8 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
|
||||
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
|
||||
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(newJustifiedBlk)))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(lastJustifiedBlk)))
|
||||
|
||||
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
||||
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
||||
@@ -228,8 +232,8 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
|
||||
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
|
||||
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(newJustifiedBlk)))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(lastJustifiedBlk)))
|
||||
|
||||
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
|
||||
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
|
||||
@@ -256,21 +260,21 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
gRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{
|
||||
Root: gRoot[:],
|
||||
}
|
||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||
service.saveInitSyncBlock(gRoot, genesis)
|
||||
service.saveInitSyncBlock(gRoot, interfaces.WrappedPhase0SignedBeaconBlock(genesis))
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
b.Block.Slot = 1
|
||||
b.Block.ParentRoot = 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.verifyBlkPreState(ctx, b.Block))
|
||||
require.NoError(t, service.verifyBlkPreState(ctx, interfaces.WrappedPhase0BeaconBlock(b.Block)))
|
||||
}
|
||||
|
||||
func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
||||
@@ -286,19 +290,19 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
gRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{
|
||||
Root: gRoot[:],
|
||||
}
|
||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
|
||||
service.saveInitSyncBlock(gRoot, genesis)
|
||||
service.saveInitSyncBlock(gRoot, interfaces.WrappedPhase0SignedBeaconBlock(genesis))
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
b.Block.Slot = 1
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
err = service.verifyBlkPreState(ctx, b.Block)
|
||||
err = service.verifyBlkPreState(ctx, interfaces.WrappedPhase0BeaconBlock(b.Block))
|
||||
wanted := "could not reconstruct parent state"
|
||||
assert.ErrorContains(t, wanted, err)
|
||||
|
||||
@@ -307,7 +311,7 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
|
||||
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
|
||||
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
|
||||
require.NoError(t, service.verifyBlkPreState(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b).Block()))
|
||||
}
|
||||
|
||||
func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
|
||||
@@ -319,7 +323,7 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
signedBlock := testutil.NewBeaconBlock()
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, signedBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(signedBlock)))
|
||||
r, err := signedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.justifiedCheckpt = ðpb.Checkpoint{Root: []byte{'A'}}
|
||||
@@ -355,7 +359,7 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
validGenesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
st, err := testutil.NewBeaconState()
|
||||
@@ -371,7 +375,7 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
|
||||
block.Block.ParentRoot = roots[8]
|
||||
|
||||
err = service.fillInForkChoiceMissingBlocks(
|
||||
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
require.NoError(t, err)
|
||||
|
||||
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
|
||||
@@ -393,7 +397,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
validGenesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
st, err := testutil.NewBeaconState()
|
||||
@@ -409,7 +413,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
|
||||
block.Block.ParentRoot = roots[8]
|
||||
|
||||
err = service.fillInForkChoiceMissingBlocks(
|
||||
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
require.NoError(t, err)
|
||||
|
||||
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
|
||||
@@ -435,7 +439,7 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
validGenesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
assert.NoError(t, err)
|
||||
st, err := testutil.NewBeaconState()
|
||||
@@ -446,23 +450,23 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
|
||||
// Define a tree branch, slot 63 <- 64 <- 65
|
||||
b63 := testutil.NewBeaconBlock()
|
||||
b63.Block.Slot = 63
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b63))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b63)))
|
||||
r63, err := b63.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b64 := testutil.NewBeaconBlock()
|
||||
b64.Block.Slot = 64
|
||||
b64.Block.ParentRoot = r63[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b64))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b64)))
|
||||
r64, err := b64.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b65 := testutil.NewBeaconBlock()
|
||||
b65.Block.Slot = 65
|
||||
b65.Block.ParentRoot = r64[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b65))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b65)))
|
||||
|
||||
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
|
||||
err = service.fillInForkChoiceMissingBlocks(
|
||||
context.Background(), b65.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(b65).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
|
||||
require.NoError(t, err)
|
||||
|
||||
// There should be 2 nodes, block 65 and block 64.
|
||||
@@ -542,7 +546,7 @@ func blockTree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][]byt
|
||||
beaconBlock := testutil.NewBeaconBlock()
|
||||
beaconBlock.Block.Slot = b.Block.Slot
|
||||
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
|
||||
if err := beaconDB.SaveBlock(context.Background(), beaconBlock); err != nil {
|
||||
if err := beaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(beaconBlock)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
|
||||
@@ -604,7 +608,7 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
|
||||
beaconBlock := testutil.NewBeaconBlock()
|
||||
beaconBlock.Block.Slot = b.Block.Slot
|
||||
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), beaconBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(beaconBlock)))
|
||||
}
|
||||
|
||||
// Slots 100 to 200 are skip slots. Requesting root at 150 will yield root at 100. The last physical block.
|
||||
@@ -686,7 +690,7 @@ func TestAncestor_CanUseDB(t *testing.T) {
|
||||
beaconBlock := testutil.NewBeaconBlock()
|
||||
beaconBlock.Block.Slot = b.Block.Slot
|
||||
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), beaconBlock)) // Saves blocks to DB.
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(beaconBlock))) // Saves blocks to DB.
|
||||
}
|
||||
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
|
||||
@@ -778,7 +782,7 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
|
||||
beaconBlock := testutil.NewBeaconBlock()
|
||||
beaconBlock.Block.Slot = b.Block.Slot
|
||||
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), beaconBlock))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(beaconBlock)))
|
||||
}
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{Root: []byte{'c'}, Epoch: 1}
|
||||
service.justifiedCheckpt.Root = r100[:]
|
||||
@@ -797,14 +801,14 @@ func TestVerifyBlkDescendant(t *testing.T) {
|
||||
b.Block.Slot = 1
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, b))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
|
||||
b1 := testutil.NewBeaconBlock()
|
||||
b1.Block.Slot = 1
|
||||
b1.Block.Body.Graffiti = bytesutil.PadTo([]byte{'a'}, 32)
|
||||
r1, err := b1.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, b1))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b1)))
|
||||
|
||||
type args struct {
|
||||
parentRoot [32]byte
|
||||
@@ -871,7 +875,7 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
|
||||
gBlk := testutil.NewBeaconBlock()
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, gBlk))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(gBlk)))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveGenesisBlockRoot(ctx, gRoot))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
|
||||
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
|
||||
@@ -927,6 +931,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
|
||||
StateGen: stategen.New(beaconDB),
|
||||
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
|
||||
DepositCache: depositCache,
|
||||
StateNotifier: &mock.MockStateNotifier{},
|
||||
}
|
||||
service, err := NewService(ctx, cfg)
|
||||
require.NoError(t, err)
|
||||
@@ -935,7 +940,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
|
||||
require.NoError(t, service.saveGenesisData(ctx, gs))
|
||||
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
|
||||
@@ -945,7 +950,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
r, err := blk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.onBlock(ctx, blk, r))
|
||||
require.NoError(t, service.onBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(blk), r))
|
||||
testState, err = service.cfg.StateGen.StateByRoot(ctx, r)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -971,7 +976,7 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
||||
require.NoError(t, service.saveGenesisData(ctx, gs))
|
||||
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
service.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
gs = gs.Copy()
|
||||
@@ -980,12 +985,12 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
||||
zeroSig := [96]byte{}
|
||||
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
|
||||
root := []byte(strconv.Itoa(int(i)))
|
||||
depositCache.InsertDeposit(ctx, ðpb.Deposit{Data: ðpb.Deposit_Data{
|
||||
assert.NoError(t, depositCache.InsertDeposit(ctx, ðpb.Deposit{Data: ðpb.Deposit_Data{
|
||||
PublicKey: bytesutil.FromBytes48([48]byte{}),
|
||||
WithdrawalCredentials: params.BeaconConfig().ZeroHash[:],
|
||||
Amount: 0,
|
||||
Signature: zeroSig[:],
|
||||
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root))
|
||||
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
|
||||
}
|
||||
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
|
||||
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/slotutil"
|
||||
|
||||
@@ -6,14 +6,15 @@ import (
|
||||
"time"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
@@ -43,13 +44,13 @@ func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
|
||||
|
||||
b32 := testutil.NewBeaconBlock()
|
||||
b32.Block.Slot = 32
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b32)))
|
||||
r32, err := b32.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b33 := testutil.NewBeaconBlock()
|
||||
b33.Block.Slot = 33
|
||||
b33.Block.ParentRoot = r32[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b33)))
|
||||
r33, err := b33.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -71,13 +72,13 @@ func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
|
||||
|
||||
b32 := testutil.NewBeaconBlock()
|
||||
b32.Block.Slot = 32
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b32)))
|
||||
r32, err := b32.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b33 := testutil.NewBeaconBlock()
|
||||
b33.Block.Slot = 33
|
||||
b33.Block.ParentRoot = r32[:]
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b33)))
|
||||
r33, err := b33.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/timeutils"
|
||||
"github.com/prysmaticlabs/prysm/shared/traceutil"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -21,8 +20,8 @@ var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
|
||||
|
||||
// BlockReceiver interface defines the methods of chain service receive and processing new blocks.
|
||||
type BlockReceiver interface {
|
||||
ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
|
||||
ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error
|
||||
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
|
||||
ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error
|
||||
HasInitSyncBlock(root [32]byte) bool
|
||||
}
|
||||
|
||||
@@ -31,11 +30,11 @@ type BlockReceiver interface {
|
||||
// 1. Validate block, apply state transition and update check points
|
||||
// 2. Apply fork choice to the processed block
|
||||
// 3. Save latest head info
|
||||
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||
func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
|
||||
defer span.End()
|
||||
receivedTime := timeutils.Now()
|
||||
blockCopy := stateV0.CopySignedBeaconBlock(block)
|
||||
blockCopy := block.Copy()
|
||||
|
||||
// Apply state transition on the new block.
|
||||
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
|
||||
@@ -53,7 +52,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.BlockProcessed,
|
||||
Data: &statefeed.BlockProcessedData{
|
||||
Slot: blockCopy.Block.Slot,
|
||||
Slot: blockCopy.Block().Slot(),
|
||||
BlockRoot: blockRoot,
|
||||
SignedBlock: blockCopy,
|
||||
Verified: true,
|
||||
@@ -62,7 +61,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
|
||||
}
|
||||
|
||||
// Handle post block operations such as attestations and exits.
|
||||
if err := s.handlePostBlockOperations(blockCopy.Block); err != nil {
|
||||
if err := s.handlePostBlockOperations(blockCopy.Block()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -72,14 +71,14 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
|
||||
}
|
||||
|
||||
// Reports on block and fork choice metrics.
|
||||
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
|
||||
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
|
||||
|
||||
// Log block sync status.
|
||||
if err := logBlockSyncStatus(blockCopy.Block, blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
|
||||
if err := logBlockSyncStatus(blockCopy.Block(), blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
|
||||
return err
|
||||
}
|
||||
// Log state transition data.
|
||||
logStateTransitionData(blockCopy.Block)
|
||||
logStateTransitionData(blockCopy.Block())
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -87,7 +86,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
|
||||
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
|
||||
// the state, performing batch verification of all collected signatures and then performing the appropriate
|
||||
// actions for a block post-transition.
|
||||
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error {
|
||||
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
|
||||
defer span.End()
|
||||
|
||||
@@ -100,7 +99,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
|
||||
}
|
||||
|
||||
for i, b := range blocks {
|
||||
blockCopy := stateV0.CopySignedBeaconBlock(b)
|
||||
blockCopy := b.Copy()
|
||||
if err = s.handleBlockAfterBatchVerify(ctx, blockCopy, blkRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
|
||||
traceutil.AnnotateError(span, err)
|
||||
return err
|
||||
@@ -109,7 +108,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
|
||||
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
|
||||
Type: statefeed.BlockProcessed,
|
||||
Data: &statefeed.BlockProcessedData{
|
||||
Slot: blockCopy.Block.Slot,
|
||||
Slot: blockCopy.Block().Slot(),
|
||||
BlockRoot: blkRoots[i],
|
||||
SignedBlock: blockCopy,
|
||||
Verified: true,
|
||||
@@ -117,7 +116,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
|
||||
})
|
||||
|
||||
// Reports on blockCopy and fork choice metrics.
|
||||
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
|
||||
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
|
||||
}
|
||||
|
||||
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
|
||||
@@ -135,24 +134,24 @@ func (s *Service) HasInitSyncBlock(root [32]byte) bool {
|
||||
return s.hasInitSyncBlock(root)
|
||||
}
|
||||
|
||||
func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
|
||||
func (s *Service) handlePostBlockOperations(b interfaces.BeaconBlock) error {
|
||||
// Delete the processed block attestations from attestation pool.
|
||||
if err := s.deletePoolAtts(b.Body.Attestations); err != nil {
|
||||
if err := s.deletePoolAtts(b.Body().Attestations()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add block attestations to the fork choice pool to compute head.
|
||||
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
|
||||
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body().Attestations()); err != nil {
|
||||
log.Errorf("Could not save block attestations for fork choice: %v", err)
|
||||
return nil
|
||||
}
|
||||
// Mark block exits as seen so we don't include same ones in future blocks.
|
||||
for _, e := range b.Body.VoluntaryExits {
|
||||
for _, e := range b.Body().VoluntaryExits() {
|
||||
s.cfg.ExitPool.MarkIncluded(e)
|
||||
}
|
||||
|
||||
// Mark attester slashings as seen so we don't include same ones in future blocks.
|
||||
for _, as := range b.Body.AttesterSlashings {
|
||||
for _, as := range b.Body().AttesterSlashings() {
|
||||
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,14 +7,15 @@ import (
|
||||
"time"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
blockchainTesting "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -53,7 +54,7 @@ func TestService_ReceiveBlock(t *testing.T) {
|
||||
if hs := s.head.state.Slot(); hs != 2 {
|
||||
t.Errorf("Unexpected state slot. Got %d but wanted %d", hs, 2)
|
||||
}
|
||||
if bs := s.head.block.Block.Slot; bs != 2 {
|
||||
if bs := s.head.block.Block().Slot(); bs != 2 {
|
||||
t.Errorf("Unexpected head block slot. Got %d but wanted %d", bs, 2)
|
||||
}
|
||||
},
|
||||
@@ -139,12 +140,12 @@ func TestService_ReceiveBlock(t *testing.T) {
|
||||
require.NoError(t, s.saveGenesisData(ctx, genesis))
|
||||
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
s.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
root, err := tt.args.block.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
err = s.ReceiveBlock(ctx, tt.args.block, root)
|
||||
err = s.ReceiveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(tt.args.block), root)
|
||||
if tt.wantedErr != "" {
|
||||
assert.ErrorContains(t, tt.wantedErr, err)
|
||||
} else {
|
||||
@@ -180,7 +181,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
|
||||
require.NoError(t, s.saveGenesisData(ctx, genesis))
|
||||
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
s.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
root, err := b.Block.HashTreeRoot()
|
||||
@@ -188,7 +189,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
require.NoError(t, s.ReceiveBlock(ctx, b, root))
|
||||
require.NoError(t, s.ReceiveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(b), root))
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
@@ -225,7 +226,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
|
||||
},
|
||||
check: func(t *testing.T, s *Service) {
|
||||
assert.Equal(t, types.Slot(2), s.head.state.Slot(), "Incorrect head state slot")
|
||||
assert.Equal(t, types.Slot(2), s.head.block.Block.Slot, "Incorrect head block slot")
|
||||
assert.Equal(t, types.Slot(2), s.head.block.Block().Slot(), "Incorrect head block slot")
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -263,12 +264,12 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
|
||||
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
gRoot, err := gBlk.Block.HashTreeRoot()
|
||||
gRoot, err := gBlk.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
s.finalizedCheckpt = ðpb.Checkpoint{Root: gRoot[:]}
|
||||
root, err := tt.args.block.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
blks := []*ethpb.SignedBeaconBlock{tt.args.block}
|
||||
blks := []interfaces.SignedBeaconBlock{interfaces.WrappedPhase0SignedBeaconBlock(tt.args.block)}
|
||||
roots := [][32]byte{root}
|
||||
err = s.ReceiveBlockBatch(ctx, blks, roots)
|
||||
if tt.wantedErr != "" {
|
||||
@@ -288,7 +289,7 @@ func TestService_HasInitSyncBlock(t *testing.T) {
|
||||
if s.HasInitSyncBlock(r) {
|
||||
t.Error("Should not have block")
|
||||
}
|
||||
s.saveInitSyncBlock(r, testutil.NewBeaconBlock())
|
||||
s.saveInitSyncBlock(r, interfaces.WrappedPhase0SignedBeaconBlock(testutil.NewBeaconBlock()))
|
||||
if !s.HasInitSyncBlock(r) {
|
||||
t.Error("Should have block")
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
@@ -28,10 +27,12 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/slotutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -60,7 +61,7 @@ type Service struct {
|
||||
nextEpochBoundarySlot types.Slot
|
||||
boundaryRoots [][32]byte
|
||||
checkpointStateCache *cache.CheckpointStateCache
|
||||
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
|
||||
initSyncBlocks map[[32]byte]interfaces.SignedBeaconBlock
|
||||
initSyncBlocksLock sync.RWMutex
|
||||
justifiedBalances []uint64
|
||||
justifiedBalancesLock sync.RWMutex
|
||||
@@ -69,21 +70,20 @@ type Service struct {
|
||||
|
||||
// Config options for the service.
|
||||
type Config struct {
|
||||
BeaconBlockBuf int
|
||||
ChainStartFetcher powchain.ChainStartFetcher
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
DepositCache *depositcache.DepositCache
|
||||
AttPool attestations.Pool
|
||||
ExitPool voluntaryexits.PoolManager
|
||||
SlashingPool slashings.PoolManager
|
||||
P2p p2p.Broadcaster
|
||||
MaxRoutines int
|
||||
StateNotifier statefeed.Notifier
|
||||
ForkChoiceStore f.ForkChoicer
|
||||
OpsService *attestations.Service
|
||||
StateGen *stategen.State
|
||||
WspBlockRoot []byte
|
||||
WspEpoch types.Epoch
|
||||
BeaconBlockBuf int
|
||||
ChainStartFetcher powchain.ChainStartFetcher
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
DepositCache *depositcache.DepositCache
|
||||
AttPool attestations.Pool
|
||||
ExitPool voluntaryexits.PoolManager
|
||||
SlashingPool slashings.PoolManager
|
||||
P2p p2p.Broadcaster
|
||||
MaxRoutines int
|
||||
StateNotifier statefeed.Notifier
|
||||
ForkChoiceStore f.ForkChoicer
|
||||
OpsService *attestations.Service
|
||||
StateGen *stategen.State
|
||||
WeakSubjectivityCheckpt *ethpb.Checkpoint
|
||||
}
|
||||
|
||||
// NewService instantiates a new block service instance that will
|
||||
@@ -96,7 +96,7 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
|
||||
cancel: cancel,
|
||||
boundaryRoots: [][32]byte{},
|
||||
checkpointStateCache: cache.NewCheckpointStateCache(),
|
||||
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
|
||||
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
|
||||
justifiedBalances: make([]uint64, 0),
|
||||
}, nil
|
||||
}
|
||||
@@ -120,8 +120,8 @@ func (s *Service) Start() {
|
||||
if err != nil {
|
||||
log.Fatalf("Could not fetch finalized cp: %v", err)
|
||||
}
|
||||
if genesisBlock != nil {
|
||||
r, err = genesisBlock.Block.HashTreeRoot()
|
||||
if genesisBlock != nil && !genesisBlock.IsNil() {
|
||||
r, err = genesisBlock.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
log.Fatalf("Could not tree hash genesis block: %v", err)
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func (s *Service) Start() {
|
||||
attestationProcessorSubscribed := make(chan struct{}, 1)
|
||||
|
||||
// If the chain has already been initialized, simply start the block processing routine.
|
||||
if beaconState != nil {
|
||||
if beaconState != nil && !beaconState.IsNil() {
|
||||
log.Info("Blockchain data already exists in DB, initializing...")
|
||||
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
|
||||
s.cfg.OpsService.SetGenesisTime(beaconState.GenesisTime())
|
||||
@@ -165,25 +165,25 @@ func (s *Service) Start() {
|
||||
}
|
||||
|
||||
// Resume fork choice.
|
||||
s.justifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
|
||||
s.justifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
|
||||
if err := s.cacheJustifiedStateBalances(s.ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))); err != nil {
|
||||
log.Fatalf("Could not cache justified state balances: %v", err)
|
||||
}
|
||||
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
|
||||
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
|
||||
s.finalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
|
||||
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
|
||||
s.prevJustifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
|
||||
s.bestJustifiedCheckpt = copyutil.CopyCheckpoint(justifiedCheckpoint)
|
||||
s.finalizedCheckpt = copyutil.CopyCheckpoint(finalizedCheckpoint)
|
||||
s.prevFinalizedCheckpt = copyutil.CopyCheckpoint(finalizedCheckpoint)
|
||||
s.resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint)
|
||||
|
||||
ss, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not get start slot of finalized epoch: %v", err)
|
||||
}
|
||||
h := s.headBlock().Block
|
||||
if h.Slot > ss {
|
||||
h := s.headBlock().Block()
|
||||
if h.Slot() > ss {
|
||||
log.WithFields(logrus.Fields{
|
||||
"startSlot": ss,
|
||||
"endSlot": h.Slot,
|
||||
"endSlot": h.Slot(),
|
||||
}).Info("Loading blocks to fork choice store, this may take a while.")
|
||||
if err := s.fillInForkChoiceMissingBlocks(s.ctx, h, s.finalizedCheckpt, s.justifiedCheckpt); err != nil {
|
||||
log.Fatalf("Could not fill in fork choice store missing blocks: %v", err)
|
||||
@@ -338,10 +338,10 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.Beacon
|
||||
return errors.Wrap(err, "could not save genesis data")
|
||||
}
|
||||
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
|
||||
if err != nil || genesisBlk == nil {
|
||||
if err != nil || genesisBlk == nil || genesisBlk.IsNil() {
|
||||
return fmt.Errorf("could not load genesis block: %v", err)
|
||||
}
|
||||
genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
|
||||
genesisBlkRoot, err := genesisBlk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get genesis block root")
|
||||
}
|
||||
@@ -352,17 +352,17 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.Beacon
|
||||
// Finalized checkpoint at genesis is a zero hash.
|
||||
genesisCheckpoint := genesisState.FinalizedCheckpoint()
|
||||
|
||||
s.justifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
|
||||
s.justifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
|
||||
if err := s.cacheJustifiedStateBalances(ctx, genesisBlkRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
|
||||
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
|
||||
s.finalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
|
||||
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
|
||||
s.prevJustifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
|
||||
s.bestJustifiedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
|
||||
s.finalizedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
|
||||
s.prevFinalizedCheckpt = copyutil.CopyCheckpoint(genesisCheckpoint)
|
||||
|
||||
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
|
||||
genesisBlk.Block.Slot,
|
||||
genesisBlk.Block().Slot(),
|
||||
genesisBlkRoot,
|
||||
params.BeaconConfig().ZeroHash,
|
||||
[32]byte{},
|
||||
@@ -381,10 +381,10 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get genesis block from db")
|
||||
}
|
||||
if genesisBlock == nil {
|
||||
if genesisBlock == nil || genesisBlock.IsNil() {
|
||||
return errors.New("no genesis block in db")
|
||||
}
|
||||
genesisBlkRoot, err := genesisBlock.Block.HashTreeRoot()
|
||||
genesisBlkRoot, err := genesisBlock.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get signing root of genesis block")
|
||||
}
|
||||
@@ -412,7 +412,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve head block")
|
||||
}
|
||||
headEpoch := helpers.SlotToEpoch(headBlock.Block.Slot)
|
||||
headEpoch := helpers.SlotToEpoch(headBlock.Block().Slot())
|
||||
var epochsSinceFinality types.Epoch
|
||||
if headEpoch > finalized.Epoch {
|
||||
epochsSinceFinality = headEpoch - finalized.Epoch
|
||||
@@ -420,7 +420,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
|
||||
// Head sync when node is far enough beyond known finalized epoch,
|
||||
// this becomes really useful during long period of non-finality.
|
||||
if epochsSinceFinality >= headSyncMinEpochsAfterCheckpoint {
|
||||
headRoot, err := headBlock.Block.HashTreeRoot()
|
||||
headRoot, err := headBlock.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not hash head block")
|
||||
}
|
||||
@@ -429,7 +429,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
|
||||
return errors.Wrap(err, "could not get finalized state from db")
|
||||
}
|
||||
log.Infof("Regenerating state from the last checkpoint at slot %d to current head slot of %d."+
|
||||
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block.Slot)
|
||||
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block().Slot())
|
||||
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve head state")
|
||||
@@ -448,7 +448,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
|
||||
return errors.Wrap(err, "could not get finalized block from db")
|
||||
}
|
||||
|
||||
if finalizedState == nil || finalizedBlock == nil {
|
||||
if finalizedState == nil || finalizedState.IsNil() || finalizedBlock == nil || finalizedBlock.IsNil() {
|
||||
return errors.New("finalized state and block can't be nil")
|
||||
}
|
||||
s.setHead(finalizedRoot, finalizedBlock, finalizedState)
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
|
||||
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
@@ -27,13 +25,16 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||
protodb "github.com/prysmaticlabs/prysm/proto/beacon/db"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type mockBeaconNode struct {
|
||||
@@ -90,7 +91,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
|
||||
require.NoError(t, err)
|
||||
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
|
||||
BeaconDB: beaconDB,
|
||||
HTTPEndpoints: []string{endpoint},
|
||||
HttpEndpoints: []string{endpoint},
|
||||
DepositContract: common.Address{},
|
||||
})
|
||||
require.NoError(t, err, "Unable to set up web3 service")
|
||||
@@ -134,7 +135,7 @@ func TestChainStartStop_Initialized(t *testing.T) {
|
||||
genesisBlk := testutil.NewBeaconBlock()
|
||||
blkRoot, err := genesisBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesisBlk)))
|
||||
s, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.SetSlot(1))
|
||||
@@ -164,7 +165,7 @@ func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
|
||||
genesisBlk := testutil.NewBeaconBlock()
|
||||
blkRoot, err := genesisBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesisBlk)))
|
||||
s, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveState(ctx, s, blkRoot))
|
||||
@@ -233,7 +234,7 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
|
||||
genesisBlk := testutil.NewBeaconBlock()
|
||||
blkRoot, err := genesisBlk.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesisBlk)))
|
||||
s, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.SetSlot(0))
|
||||
@@ -260,7 +261,7 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
|
||||
genesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
|
||||
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
|
||||
headBlock := testutil.NewBeaconBlock()
|
||||
@@ -274,13 +275,13 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
|
||||
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(headBlock)))
|
||||
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, ðpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
|
||||
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
|
||||
require.NoError(t, c.initializeChainInfo(ctx))
|
||||
headBlk, err := c.HeadBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, headBlock, headBlk, "Head block incorrect")
|
||||
assert.DeepEqual(t, headBlock, headBlk.Proto(), "Head block incorrect")
|
||||
s, err := c.HeadState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
|
||||
@@ -301,7 +302,7 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
|
||||
genesisRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesis)))
|
||||
|
||||
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
|
||||
headBlock := testutil.NewBeaconBlock()
|
||||
@@ -315,14 +316,14 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
|
||||
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(headBlock)))
|
||||
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
|
||||
require.NoError(t, c.initializeChainInfo(ctx))
|
||||
s, err := c.HeadState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
|
||||
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
|
||||
assert.DeepEqual(t, genesis, c.head.block)
|
||||
assert.DeepEqual(t, genesis, c.head.block.Proto())
|
||||
}
|
||||
|
||||
func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
@@ -343,14 +344,14 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(genesisBlock)))
|
||||
|
||||
finalizedBlock := testutil.NewBeaconBlock()
|
||||
finalizedBlock.Block.Slot = finalizedSlot
|
||||
finalizedBlock.Block.ParentRoot = genesisRoot[:]
|
||||
finalizedRoot, err := finalizedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, finalizedBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(finalizedBlock)))
|
||||
|
||||
// Set head slot close to the finalization point, no head sync is triggered.
|
||||
headBlock := testutil.NewBeaconBlock()
|
||||
@@ -358,7 +359,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
headBlock.Block.ParentRoot = finalizedRoot[:]
|
||||
headRoot, err := headBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(headBlock)))
|
||||
|
||||
headState, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
@@ -381,7 +382,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
|
||||
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
|
||||
// Since head sync is not triggered, chain is initialized to the last finalization checkpoint.
|
||||
assert.DeepEqual(t, finalizedBlock, c.head.block)
|
||||
assert.DeepEqual(t, finalizedBlock, c.head.block.Proto())
|
||||
assert.LogsContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
|
||||
assert.LogsDoNotContain(t, hook, "Regenerating state from the last checkpoint at slot")
|
||||
|
||||
@@ -391,7 +392,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
headBlock.Block.ParentRoot = finalizedRoot[:]
|
||||
headRoot, err = headBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
|
||||
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(headBlock)))
|
||||
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
|
||||
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
|
||||
|
||||
@@ -402,7 +403,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
|
||||
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
|
||||
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
|
||||
// Head slot is far beyond the latest finalized checkpoint, head sync is triggered.
|
||||
assert.DeepEqual(t, headBlock, c.head.block)
|
||||
assert.DeepEqual(t, headBlock, c.head.block.Proto())
|
||||
assert.LogsContain(t, hook, "Regenerating state from the last checkpoint at slot 225")
|
||||
assert.LogsDoNotContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
|
||||
}
|
||||
@@ -420,7 +421,7 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
|
||||
newState, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.cfg.StateGen.SaveState(ctx, r, newState))
|
||||
require.NoError(t, s.saveHeadNoDB(ctx, blk, r, newState))
|
||||
require.NoError(t, s.saveHeadNoDB(ctx, interfaces.WrappedPhase0SignedBeaconBlock(blk), r, newState))
|
||||
|
||||
newB, err := s.cfg.BeaconDB.HeadBlock(ctx)
|
||||
require.NoError(t, err)
|
||||
@@ -441,7 +442,7 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
beaconState, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, beaconState))
|
||||
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, interfaces.WrappedPhase0SignedBeaconBlock(block).Block(), r, beaconState))
|
||||
|
||||
assert.Equal(t, false, s.hasBlock(ctx, [32]byte{}), "Should not have block")
|
||||
assert.Equal(t, true, s.hasBlock(ctx, r), "Should have block")
|
||||
@@ -454,12 +455,12 @@ func TestServiceStop_SaveCachedBlocks(t *testing.T) {
|
||||
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
|
||||
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
|
||||
}
|
||||
b := testutil.NewBeaconBlock()
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
block := testutil.NewBeaconBlock()
|
||||
r, err := block.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
s.saveInitSyncBlock(r, b)
|
||||
s.saveInitSyncBlock(r, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
require.NoError(t, s.Stop())
|
||||
require.Equal(t, true, s.cfg.BeaconDB.HasBlock(ctx, r))
|
||||
}
|
||||
@@ -485,7 +486,7 @@ func BenchmarkHasBlockDB(b *testing.B) {
|
||||
cfg: &Config{BeaconDB: beaconDB},
|
||||
}
|
||||
block := testutil.NewBeaconBlock()
|
||||
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, block))
|
||||
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, interfaces.WrappedPhase0SignedBeaconBlock(block)))
|
||||
r, err := block.Block.HashTreeRoot()
|
||||
require.NoError(b, err)
|
||||
|
||||
@@ -508,7 +509,7 @@ func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
|
||||
bs := &pb.BeaconState{FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, 32)}}
|
||||
beaconState, err := stateV0.InitializeFromProto(bs)
|
||||
require.NoError(b, err)
|
||||
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, beaconState))
|
||||
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, interfaces.WrappedPhase0SignedBeaconBlock(block).Block(), r, beaconState))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
||||
@@ -21,11 +21,13 @@ go_library(
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/event:go_default_library",
|
||||
"//shared/interfaces:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
blockfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/block"
|
||||
@@ -22,7 +21,10 @@ import (
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/event"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -31,11 +33,11 @@ import (
|
||||
type ChainService struct {
|
||||
State iface.BeaconState
|
||||
Root []byte
|
||||
Block *ethpb.SignedBeaconBlock
|
||||
Block interfaces.SignedBeaconBlock
|
||||
FinalizedCheckPoint *ethpb.Checkpoint
|
||||
CurrentJustifiedCheckPoint *ethpb.Checkpoint
|
||||
PreviousJustifiedCheckPoint *ethpb.Checkpoint
|
||||
BlocksReceived []*ethpb.SignedBeaconBlock
|
||||
BlocksReceived []interfaces.SignedBeaconBlock
|
||||
Balance *precompute.Balance
|
||||
Genesis time.Time
|
||||
ValidatorsRoot [32]byte
|
||||
@@ -148,18 +150,18 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
|
||||
}
|
||||
|
||||
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
|
||||
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
|
||||
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
|
||||
if s.State == nil {
|
||||
s.State = &stateV0.BeaconState{}
|
||||
}
|
||||
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
|
||||
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
|
||||
}
|
||||
if err := s.State.SetSlot(block.Block.Slot); err != nil {
|
||||
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
|
||||
return err
|
||||
}
|
||||
s.BlocksReceived = append(s.BlocksReceived, block)
|
||||
signingRoot, err := block.Block.HashTreeRoot()
|
||||
signingRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -167,7 +169,7 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb
|
||||
if err := s.DB.SaveBlock(ctx, block); err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
|
||||
}
|
||||
s.Root = signingRoot[:]
|
||||
s.Block = block
|
||||
@@ -175,19 +177,19 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb
|
||||
}
|
||||
|
||||
// ReceiveBlockBatch processes blocks in batches from initial-sync.
|
||||
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, _ [][32]byte) error {
|
||||
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock, _ [][32]byte) error {
|
||||
if s.State == nil {
|
||||
s.State = &stateV0.BeaconState{}
|
||||
}
|
||||
for _, block := range blks {
|
||||
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
|
||||
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
|
||||
}
|
||||
if err := s.State.SetSlot(block.Block.Slot); err != nil {
|
||||
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
|
||||
return err
|
||||
}
|
||||
s.BlocksReceived = append(s.BlocksReceived, block)
|
||||
signingRoot, err := block.Block.HashTreeRoot()
|
||||
signingRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -195,7 +197,7 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sign
|
||||
if err := s.DB.SaveBlock(ctx, block); err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
|
||||
}
|
||||
s.Root = signingRoot[:]
|
||||
s.Block = block
|
||||
@@ -204,18 +206,18 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sign
|
||||
}
|
||||
|
||||
// ReceiveBlock mocks ReceiveBlock method in chain service.
|
||||
func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
|
||||
func (s *ChainService) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
|
||||
if s.State == nil {
|
||||
s.State = &stateV0.BeaconState{}
|
||||
}
|
||||
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
|
||||
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
|
||||
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
|
||||
}
|
||||
if err := s.State.SetSlot(block.Block.Slot); err != nil {
|
||||
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
|
||||
return err
|
||||
}
|
||||
s.BlocksReceived = append(s.BlocksReceived, block)
|
||||
signingRoot, err := block.Block.HashTreeRoot()
|
||||
signingRoot, err := block.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -223,7 +225,7 @@ func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeac
|
||||
if err := s.DB.SaveBlock(ctx, block); err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
|
||||
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
|
||||
}
|
||||
s.Root = signingRoot[:]
|
||||
s.Block = block
|
||||
@@ -247,7 +249,7 @@ func (s *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
|
||||
}
|
||||
|
||||
// HeadBlock mocks HeadBlock method in chain service.
|
||||
func (s *ChainService) HeadBlock(context.Context) (*ethpb.SignedBeaconBlock, error) {
|
||||
func (s *ChainService) HeadBlock(context.Context) (interfaces.SignedBeaconBlock, error) {
|
||||
return s.Block, nil
|
||||
}
|
||||
|
||||
@@ -385,5 +387,9 @@ func (s *ChainService) VerifyFinalizedConsistency(_ context.Context, r []byte) e
|
||||
|
||||
// ChainHeads mocks ChainHeads and always return nil.
|
||||
func (s *ChainService) ChainHeads() ([][32]byte, []types.Slot) {
|
||||
return [][32]byte{}, []types.Slot{}
|
||||
return [][32]byte{
|
||||
bytesutil.ToBytes32(bytesutil.PadTo([]byte("foo"), 32)),
|
||||
bytesutil.ToBytes32(bytesutil.PadTo([]byte("bar"), 32)),
|
||||
},
|
||||
[]types.Slot{0, 1}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
// Reference design: https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/weak-subjectivity.md#weak-subjectivity-sync-procedure
|
||||
func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
|
||||
// TODO(7342): Remove the following to fully use weak subjectivity in production.
|
||||
if len(s.cfg.WspBlockRoot) == 0 || s.cfg.WspEpoch == 0 {
|
||||
if s.cfg.WeakSubjectivityCheckpt == nil || len(s.cfg.WeakSubjectivityCheckpt.Root) == 0 || s.cfg.WeakSubjectivityCheckpt.Epoch == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
|
||||
if s.wsVerified {
|
||||
return nil
|
||||
}
|
||||
if s.cfg.WspEpoch > s.finalizedCheckpt.Epoch {
|
||||
if s.cfg.WeakSubjectivityCheckpt.Epoch > s.finalizedCheckpt.Epoch {
|
||||
return nil
|
||||
}
|
||||
|
||||
r := bytesutil.ToBytes32(s.cfg.WspBlockRoot)
|
||||
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.cfg.WspEpoch)
|
||||
r := bytesutil.ToBytes32(s.cfg.WeakSubjectivityCheckpt.Root)
|
||||
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
|
||||
// Save initial sync cached blocks to DB.
|
||||
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
|
||||
return err
|
||||
@@ -38,7 +38,7 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
|
||||
return fmt.Errorf("node does not have root in DB: %#x", r)
|
||||
}
|
||||
|
||||
startSlot, err := helpers.StartSlot(s.cfg.WspEpoch)
|
||||
startSlot, err := helpers.StartSlot(s.cfg.WeakSubjectivityCheckpt.Epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,5 +56,5 @@ func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WspEpoch)
|
||||
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
@@ -16,14 +18,13 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||
|
||||
b := testutil.NewBeaconBlock()
|
||||
b.Block.Slot = 32
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), b))
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.WrappedPhase0SignedBeaconBlock(b)))
|
||||
r, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
wsVerified bool
|
||||
wantErr bool
|
||||
wsRoot [32]byte
|
||||
wsEpoch types.Epoch
|
||||
checkpt *ethpb.Checkpoint
|
||||
finalizedEpoch types.Epoch
|
||||
errString string
|
||||
name string
|
||||
@@ -34,37 +35,34 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "already verified",
|
||||
wsEpoch: 2,
|
||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
||||
finalizedEpoch: 2,
|
||||
wsVerified: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "not yet to verify, ws epoch higher than finalized epoch",
|
||||
wsEpoch: 2,
|
||||
checkpt: ðpb.Checkpoint{Epoch: 2},
|
||||
finalizedEpoch: 1,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "can't find the block in DB",
|
||||
wsEpoch: 1,
|
||||
wsRoot: [32]byte{'a'},
|
||||
checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: 1},
|
||||
finalizedEpoch: 3,
|
||||
wantErr: true,
|
||||
errString: "node does not have root in DB",
|
||||
},
|
||||
{
|
||||
name: "can't find the block corresponds to ws epoch in DB",
|
||||
wsEpoch: 2,
|
||||
wsRoot: r, // Root belongs in epoch 1.
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 2}, // Root belongs in epoch 1.
|
||||
finalizedEpoch: 3,
|
||||
wantErr: true,
|
||||
errString: "node does not have root in db corresponding to epoch",
|
||||
},
|
||||
{
|
||||
name: "can verify and pass",
|
||||
wsEpoch: 1,
|
||||
wsRoot: r,
|
||||
checkpt: ðpb.Checkpoint{Root: r[:], Epoch: 1},
|
||||
finalizedEpoch: 3,
|
||||
wantErr: false,
|
||||
},
|
||||
@@ -72,7 +70,7 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &Service{
|
||||
cfg: &Config{BeaconDB: beaconDB, WspBlockRoot: tt.wsRoot[:], WspEpoch: tt.wsEpoch},
|
||||
cfg: &Config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
|
||||
wsVerified: tt.wsVerified,
|
||||
finalizedCheckpt: ðpb.Checkpoint{Epoch: tt.finalizedEpoch},
|
||||
}
|
||||
|
||||
8
beacon-chain/cache/BUILD.bazel
vendored
8
beacon-chain/cache/BUILD.bazel
vendored
@@ -32,7 +32,8 @@ go_library(
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/copyutil:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/sliceutil:go_default_library",
|
||||
@@ -41,7 +42,6 @@ go_library(
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@io_k8s_client_go//tools/cache:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
@@ -65,13 +65,13 @@ go_test(
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_google_gofuzz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
6
beacon-chain/cache/attestation_data.go
vendored
6
beacon-chain/cache/attestation_data.go
vendored
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
@@ -98,7 +98,7 @@ func (c *AttestationCache) Get(ctx context.Context, req *ethpb.AttestationDataRe
|
||||
|
||||
if exists && item != nil && item.(*attestationReqResWrapper).res != nil {
|
||||
attestationCacheHit.Inc()
|
||||
return stateV0.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
|
||||
return copyutil.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
|
||||
}
|
||||
attestationCacheMiss.Inc()
|
||||
return nil, nil
|
||||
|
||||
4
beacon-chain/cache/attestation_data_test.go
vendored
4
beacon-chain/cache/attestation_data_test.go
vendored
@@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestAttestationCache_RoundTrip(t *testing.T) {
|
||||
|
||||
2
beacon-chain/cache/checkpoint_state.go
vendored
2
beacon-chain/cache/checkpoint_state.go
vendored
@@ -6,8 +6,8 @@ import (
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
)
|
||||
|
||||
|
||||
4
beacon-chain/cache/checkpoint_state_test.go
vendored
4
beacon-chain/cache/checkpoint_state_test.go
vendored
@@ -3,16 +3,16 @@ package cache
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
|
||||
|
||||
40
beacon-chain/cache/committee.go
vendored
40
beacon-chain/cache/committee.go
vendored
@@ -6,12 +6,12 @@ import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/sliceutil"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -33,7 +33,7 @@ var (
|
||||
|
||||
// CommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
|
||||
type CommitteeCache struct {
|
||||
CommitteeCache *cache.FIFO
|
||||
CommitteeCache *lru.Cache
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
@@ -43,14 +43,19 @@ func committeeKeyFn(obj interface{}) (string, error) {
|
||||
if !ok {
|
||||
return "", ErrNotCommittee
|
||||
}
|
||||
|
||||
return key(info.Seed), nil
|
||||
}
|
||||
|
||||
// NewCommitteesCache creates a new committee cache for storing/accessing shuffled indices of a committee.
|
||||
func NewCommitteesCache() *CommitteeCache {
|
||||
cCache, err := lru.New(int(maxCommitteesCacheSize))
|
||||
// An error is only returned if the size of the cache is
|
||||
// <= 0.
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &CommitteeCache{
|
||||
CommitteeCache: cache.NewFIFO(committeeKeyFn),
|
||||
CommitteeCache: cCache,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +65,7 @@ func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.C
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj, exists := c.CommitteeCache.Get(key(seed))
|
||||
if exists {
|
||||
CommitteeCacheHit.Inc()
|
||||
} else {
|
||||
@@ -97,11 +98,11 @@ func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.C
|
||||
func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
if err := c.CommitteeCache.AddIfNotPresent(committees); err != nil {
|
||||
key, err := committeeKeyFn(committees)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trim(c.CommitteeCache, maxCommitteesCacheSize)
|
||||
_ = c.CommitteeCache.Add(key, committees)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,10 +110,7 @@ func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error
|
||||
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj, exists := c.CommitteeCache.Get(key(seed))
|
||||
|
||||
if exists {
|
||||
CommitteeCacheHit.Inc()
|
||||
@@ -133,11 +131,7 @@ func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, e
|
||||
func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
obj, exists := c.CommitteeCache.Get(key(seed))
|
||||
if exists {
|
||||
CommitteeCacheHit.Inc()
|
||||
} else {
|
||||
@@ -155,8 +149,8 @@ func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
|
||||
|
||||
// HasEntry returns true if the committee cache has a value.
|
||||
func (c *CommitteeCache) HasEntry(seed string) bool {
|
||||
_, ok, err := c.CommitteeCache.GetByKey(seed)
|
||||
return err == nil && ok
|
||||
_, ok := c.CommitteeCache.Get(seed)
|
||||
return ok
|
||||
}
|
||||
|
||||
func startEndIndices(c *Committees, index uint64) (uint64, uint64) {
|
||||
|
||||
4
beacon-chain/cache/committee_fuzz_test.go
vendored
4
beacon-chain/cache/committee_fuzz_test.go
vendored
@@ -32,7 +32,7 @@ func TestCommitteeCache_FuzzCommitteesByEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
|
||||
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
|
||||
}
|
||||
|
||||
func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
|
||||
@@ -49,5 +49,5 @@ func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
|
||||
assert.DeepEqual(t, c.SortedIndices, indices)
|
||||
}
|
||||
|
||||
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
|
||||
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
|
||||
}
|
||||
|
||||
12
beacon-chain/cache/committee_test.go
vendored
12
beacon-chain/cache/committee_test.go
vendored
@@ -100,11 +100,11 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
|
||||
require.NoError(t, cache.AddCommitteeShuffledList(item))
|
||||
}
|
||||
|
||||
k := cache.CommitteeCache.ListKeys()
|
||||
k := cache.CommitteeCache.Keys()
|
||||
assert.Equal(t, maxCommitteesCacheSize, uint64(len(k)))
|
||||
|
||||
sort.Slice(k, func(i, j int) bool {
|
||||
return k[i] < k[j]
|
||||
return k[i].(string) < k[j].(string)
|
||||
})
|
||||
wanted := end - int(maxCommitteesCacheSize)
|
||||
s := bytesutil.ToBytes32([]byte(strconv.Itoa(wanted)))
|
||||
@@ -117,13 +117,15 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
|
||||
func TestCommitteeCacheOutOfRange(t *testing.T) {
|
||||
cache := NewCommitteesCache()
|
||||
seed := bytesutil.ToBytes32([]byte("foo"))
|
||||
err := cache.CommitteeCache.Add(&Committees{
|
||||
comms := &Committees{
|
||||
CommitteeCount: 1,
|
||||
Seed: seed,
|
||||
ShuffledIndices: []types.ValidatorIndex{0},
|
||||
SortedIndices: []types.ValidatorIndex{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
key, err := committeeKeyFn(comms)
|
||||
assert.NoError(t, err)
|
||||
_ = cache.CommitteeCache.Add(key, comms)
|
||||
|
||||
_, err = cache.Committee(0, seed, math.MaxUint64) // Overflow!
|
||||
require.NotNil(t, err, "Did not fail as expected")
|
||||
|
||||
7
beacon-chain/cache/depositcache/BUILD.bazel
vendored
7
beacon-chain/cache/depositcache/BUILD.bazel
vendored
@@ -12,13 +12,14 @@ go_library(
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/beacon/db:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/trieutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
@@ -33,13 +34,13 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/beacon/db:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"//shared/trieutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -12,10 +12,11 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/trieutil"
|
||||
@@ -74,7 +75,7 @@ func New() (*DepositCache, error) {
|
||||
|
||||
// InsertDeposit into the database. If deposit or block number are nil
|
||||
// then this method does nothing.
|
||||
func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) {
|
||||
func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.InsertDeposit")
|
||||
defer span.End()
|
||||
if d == nil {
|
||||
@@ -84,10 +85,14 @@ func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blo
|
||||
"index": index,
|
||||
"deposit root": hex.EncodeToString(depositRoot[:]),
|
||||
}).Warn("Ignoring nil deposit insertion")
|
||||
return
|
||||
return errors.New("nil deposit inserted into the cache")
|
||||
}
|
||||
dc.depositsLock.Lock()
|
||||
defer dc.depositsLock.Unlock()
|
||||
|
||||
if int(index) != len(dc.deposits) {
|
||||
return errors.Errorf("wanted deposit with index %d to be inserted but received %d", len(dc.deposits), index)
|
||||
}
|
||||
// Keep the slice sorted on insertion in order to avoid costly sorting on retrieval.
|
||||
heightIdx := sort.Search(len(dc.deposits), func(i int) bool { return dc.deposits[i].Index >= index })
|
||||
newDeposits := append(
|
||||
@@ -95,6 +100,7 @@ func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blo
|
||||
dc.deposits[heightIdx:]...)
|
||||
dc.deposits = append(dc.deposits[:heightIdx], newDeposits...)
|
||||
historicalDepositsCount.Inc()
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertDepositContainers inserts a set of deposit containers into our deposit cache.
|
||||
@@ -167,7 +173,7 @@ func (dc *DepositCache) AllDeposits(ctx context.Context, untilBlk *big.Int) []*e
|
||||
return deposits
|
||||
}
|
||||
|
||||
// DepositsNumberAndRootAtHeight returns number of deposits made prior to blockheight and the
|
||||
// DepositsNumberAndRootAtHeight returns number of deposits made up to blockheight and the
|
||||
// root that corresponds to the latest deposit at that blockheight.
|
||||
func (dc *DepositCache) DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte) {
|
||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.DepositsNumberAndRootAtHeight")
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -26,7 +26,7 @@ func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{})
|
||||
assert.ErrorContains(t, "nil deposit inserted into the cache", dc.InsertDeposit(context.Background(), nil, 1, 0, [32]byte{}))
|
||||
|
||||
require.Equal(t, 0, len(dc.deposits), "Number of deposits changed")
|
||||
assert.Equal(t, nilDepositErr, hook.LastEntry().Message)
|
||||
@@ -37,37 +37,52 @@ func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
insertions := []struct {
|
||||
blkNum uint64
|
||||
deposit *ethpb.Deposit
|
||||
index int64
|
||||
blkNum uint64
|
||||
deposit *ethpb.Deposit
|
||||
index int64
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 0,
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 0,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 3,
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 3,
|
||||
expectedErr: "wanted deposit with index 1 to be inserted but received 3",
|
||||
},
|
||||
{
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 1,
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 1,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 4,
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 4,
|
||||
expectedErr: "wanted deposit with index 2 to be inserted but received 4",
|
||||
},
|
||||
{
|
||||
blkNum: 0,
|
||||
deposit: ðpb.Deposit{},
|
||||
index: 2,
|
||||
expectedErr: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, ins := range insertions {
|
||||
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
|
||||
if ins.expectedErr != "" {
|
||||
assert.ErrorContains(t, ins.expectedErr, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
} else {
|
||||
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
}
|
||||
}
|
||||
|
||||
expectedIndices := []int64{0, 1, 3, 4}
|
||||
expectedIndices := []int64{0, 1, 2}
|
||||
for i, ei := range expectedIndices {
|
||||
assert.Equal(t, ei, dc.deposits[i].Index,
|
||||
fmt.Sprintf("dc.deposits[%d].Index = %d, wanted %d", i, dc.deposits[i].Index, ei))
|
||||
@@ -154,121 +169,148 @@ func TestAllDeposits_FiltersDepositUpToAndIncludingBlockNumber(t *testing.T) {
|
||||
assert.Equal(t, 5, len(d))
|
||||
}
|
||||
|
||||
func TestDepositsNumberAndRootAtHeight_ReturnsAppropriateCountAndRoot(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
func TestDepositsNumberAndRootAtHeight(t *testing.T) {
|
||||
wantedRoot := bytesutil.PadTo([]byte("root"), 32)
|
||||
t.Run("requesting_last_item_works", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Index: 1,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 11,
|
||||
Index: 2,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 13,
|
||||
Index: 3,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(13))
|
||||
assert.Equal(t, 4, int(n))
|
||||
require.DeepEqual(t, wantedRoot, root[:])
|
||||
})
|
||||
t.Run("only_one_item", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 11,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 12,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 12,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
|
||||
assert.Equal(t, 1, int(n))
|
||||
require.DeepEqual(t, wantedRoot, root[:])
|
||||
})
|
||||
t.Run("none_at_height_some_below", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(11))
|
||||
assert.Equal(t, 5, int(n))
|
||||
assert.Equal(t, bytesutil.ToBytes32([]byte("root")), root)
|
||||
}
|
||||
|
||||
func TestDepositsNumberAndRootAtHeight_ReturnsEmptyTrieIfBlockHeightLessThanOldestDeposit(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 8,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 11,
|
||||
Deposit: ðpb.Deposit{
|
||||
Data: ðpb.Deposit_Data{
|
||||
PublicKey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Signature: make([]byte, 96),
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 9,
|
||||
Index: 1,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
DepositRoot: bytesutil.PadTo([]byte("root"), 32),
|
||||
},
|
||||
}
|
||||
{
|
||||
Eth1BlockHeight: 11,
|
||||
Index: 2,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
|
||||
assert.Equal(t, 2, int(n))
|
||||
require.DeepEqual(t, wantedRoot, root[:])
|
||||
})
|
||||
t.Run("none_at_height_none_below", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(2))
|
||||
assert.Equal(t, 0, int(n))
|
||||
assert.Equal(t, [32]byte{}, root)
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 8,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(7))
|
||||
assert.Equal(t, 0, int(n))
|
||||
require.DeepEqual(t, params.BeaconConfig().ZeroHash, root)
|
||||
})
|
||||
t.Run("none_at_height_one_below", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 8,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(10))
|
||||
assert.Equal(t, 1, int(n))
|
||||
require.DeepEqual(t, wantedRoot, root[:])
|
||||
})
|
||||
t.Run("some_greater_some_lower", func(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
dc.deposits = []*dbpb.DepositContainer{
|
||||
{
|
||||
Eth1BlockHeight: 8,
|
||||
Index: 0,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 8,
|
||||
Index: 1,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 9,
|
||||
Index: 2,
|
||||
Deposit: ðpb.Deposit{},
|
||||
DepositRoot: wantedRoot,
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Index: 3,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
{
|
||||
Eth1BlockHeight: 10,
|
||||
Index: 4,
|
||||
Deposit: ðpb.Deposit{},
|
||||
},
|
||||
}
|
||||
n, root := dc.DepositsNumberAndRootAtHeight(context.Background(), big.NewInt(9))
|
||||
assert.Equal(t, 3, int(n))
|
||||
require.DeepEqual(t, wantedRoot, root[:])
|
||||
})
|
||||
}
|
||||
|
||||
func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
|
||||
@@ -606,7 +648,7 @@ func TestPruneProofs_Ok(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, ins := range deposits {
|
||||
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
|
||||
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
}
|
||||
|
||||
require.NoError(t, dc.PruneProofs(context.Background(), 1))
|
||||
@@ -649,7 +691,7 @@ func TestPruneProofs_SomeAlreadyPruned(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, ins := range deposits {
|
||||
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
|
||||
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
}
|
||||
|
||||
require.NoError(t, dc.PruneProofs(context.Background(), 2))
|
||||
@@ -689,7 +731,7 @@ func TestPruneProofs_PruneAllWhenDepositIndexTooBig(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, ins := range deposits {
|
||||
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
|
||||
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
}
|
||||
|
||||
require.NoError(t, dc.PruneProofs(context.Background(), 99))
|
||||
@@ -732,7 +774,7 @@ func TestPruneProofs_CorrectlyHandleLastIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, ins := range deposits {
|
||||
dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{})
|
||||
assert.NoError(t, dc.InsertDeposit(context.Background(), ins.deposit, ins.blkNum, ins.index, [32]byte{}))
|
||||
}
|
||||
|
||||
require.NoError(t, dc.PruneProofs(context.Background(), 4))
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var _ PendingDepositsFetcher = (*DepositCache)(nil)
|
||||
@@ -90,7 +90,7 @@ func TestPendingDeposits_OK(t *testing.T) {
|
||||
{Proof: [][]byte{[]byte("A")}},
|
||||
{Proof: [][]byte{[]byte("B")}},
|
||||
}
|
||||
assert.DeepEqual(t, expected, deposits)
|
||||
assert.DeepSSZEqual(t, expected, deposits)
|
||||
|
||||
all := dc.PendingDeposits(context.Background(), nil)
|
||||
assert.Equal(t, len(dc.pendingDeposits), len(all), "PendingDeposits(ctx, nil) did not return all deposits")
|
||||
|
||||
@@ -21,30 +21,32 @@ go_library(
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//fuzz:__pkg__",
|
||||
"//shared/testutil:__pkg__",
|
||||
"//spectest:__subpackages__",
|
||||
"//validator/accounts:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/copyutil:go_default_library",
|
||||
"//shared/depositutil:go_default_library",
|
||||
"//shared/hashutil:go_default_library",
|
||||
"//shared/interfaces:go_default_library",
|
||||
"//shared/mathutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/slashutil:go_default_library",
|
||||
"//shared/sliceutil:go_default_library",
|
||||
"//shared/trieutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -71,25 +73,28 @@ go_test(
|
||||
shard_count = 2,
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/p2p/types:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/aggregation:go_default_library",
|
||||
"//shared/aggregation/attestations:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/bls:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/copyutil:go_default_library",
|
||||
"//shared/interfaces:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"//shared/trieutil:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_google_gofuzz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -6,12 +6,13 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
@@ -21,14 +22,14 @@ import (
|
||||
func ProcessAttestations(
|
||||
ctx context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
b interfaces.SignedBeaconBlock,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var err error
|
||||
for idx, attestation := range b.Block.Body.Attestations {
|
||||
for idx, attestation := range b.Block().Body().Attestations() {
|
||||
beaconState, err = ProcessAttestation(ctx, beaconState, attestation)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
|
||||
@@ -64,7 +65,7 @@ func ProcessAttestations(
|
||||
// assert data.source == state.previous_justified_checkpoint
|
||||
// state.previous_epoch_attestations.append(pending_attestation)
|
||||
//
|
||||
// # Check signature
|
||||
// # Verify signature
|
||||
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
|
||||
func ProcessAttestation(
|
||||
ctx context.Context,
|
||||
@@ -83,14 +84,14 @@ func ProcessAttestation(
|
||||
func ProcessAttestationsNoVerifySignature(
|
||||
ctx context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
b interfaces.SignedBeaconBlock,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := b.Block.Body
|
||||
body := b.Block().Body()
|
||||
var err error
|
||||
for idx, attestation := range body.Attestations {
|
||||
for idx, attestation := range body.Attestations() {
|
||||
beaconState, err = ProcessAttestationNoVerifySignature(ctx, beaconState, attestation)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
|
||||
@@ -6,17 +6,18 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/aggregation"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -46,7 +47,7 @@ func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
|
||||
params.BeaconConfig().MinAttestationInclusionDelay,
|
||||
beaconState.Slot(),
|
||||
)
|
||||
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err := blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
|
||||
helpers.PrevEpoch(beaconState),
|
||||
helpers.CurrentEpoch(beaconState),
|
||||
)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -104,11 +105,11 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
|
||||
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
|
||||
|
||||
want := "source check point not equal to current justified checkpoint"
|
||||
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err := blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
|
||||
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -142,12 +143,12 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
|
||||
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
|
||||
|
||||
want := "source check point not equal to previous justified checkpoint"
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
|
||||
b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.PrevEpoch(beaconState)
|
||||
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
|
||||
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
|
||||
|
||||
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, expected, err)
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ func TestProcessAttestations_OK(t *testing.T) {
|
||||
|
||||
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
|
||||
require.NoError(t, err)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -352,7 +353,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
|
||||
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
|
||||
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -783,3 +784,64 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
|
||||
}
|
||||
|
||||
func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
|
||||
validators := make([]*ethpb.Validator, numOfValidators)
|
||||
_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
|
||||
require.NoError(t, err)
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = ðpb.Validator{
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
PublicKey: keys[i].PublicKey().Marshal(),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
}
|
||||
}
|
||||
|
||||
st, err := testutil.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, st.SetSlot(5))
|
||||
require.NoError(t, st.SetValidators(validators))
|
||||
require.NoError(t, st.SetFork(&pb.Fork{Epoch: 1, CurrentVersion: []byte{0, 1, 2, 3}, PreviousVersion: []byte{0, 1, 1, 1}}))
|
||||
|
||||
comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
|
||||
require.NoError(t, err)
|
||||
att1 := testutil.HydrateAttestation(ðpb.Attestation{
|
||||
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
},
|
||||
})
|
||||
domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
|
||||
require.NoError(t, err)
|
||||
root, err := helpers.ComputeSigningRoot(att1.Data, domain)
|
||||
require.NoError(t, err)
|
||||
var sigs []bls.Signature
|
||||
for i, u := range comm1 {
|
||||
att1.AggregationBits.SetBitAt(uint64(i), true)
|
||||
sigs = append(sigs, keys[u].Sign(root[:]))
|
||||
}
|
||||
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
|
||||
comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
|
||||
require.NoError(t, err)
|
||||
att2 := testutil.HydrateAttestation(ðpb.Attestation{
|
||||
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
CommitteeIndex: 1,
|
||||
},
|
||||
})
|
||||
root, err = helpers.ComputeSigningRoot(att2.Data, domain)
|
||||
require.NoError(t, err)
|
||||
sigs = nil
|
||||
for i, u := range comm2 {
|
||||
att2.AggregationBits.SetBitAt(uint64(i), true)
|
||||
sigs = append(sigs, keys[u].Sign(root[:]))
|
||||
}
|
||||
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
|
||||
_, err = blocks.AttestationSignatureSet(ctx, st, []*ethpb.Attestation{att1, att2})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/slashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/sliceutil"
|
||||
@@ -37,14 +36,10 @@ import (
|
||||
func ProcessAttesterSlashings(
|
||||
ctx context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
slashings []*ethpb.AttesterSlashing,
|
||||
slashFunc slashValidatorFunc,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
for idx, slashing := range body.AttesterSlashings {
|
||||
for idx, slashing := range slashings {
|
||||
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
|
||||
return nil, errors.Wrapf(err, "could not verify attester slashing %d", idx)
|
||||
}
|
||||
@@ -62,7 +57,7 @@ func ProcessAttesterSlashings(
|
||||
return nil, err
|
||||
}
|
||||
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
|
||||
beaconState, err = v.SlashValidator(beaconState, types.ValidatorIndex(validatorIndex))
|
||||
beaconState, err = slashFunc(beaconState, types.ValidatorIndex(validatorIndex))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not slash validator index %d",
|
||||
validatorIndex)
|
||||
|
||||
@@ -5,11 +5,12 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
@@ -57,7 +58,7 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
|
||||
AttesterSlashings: slashings,
|
||||
},
|
||||
}
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
assert.ErrorContains(t, "attestations are not slashable", err)
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
|
||||
},
|
||||
}
|
||||
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
assert.ErrorContains(t, "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE", err)
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ import (
|
||||
|
||||
fuzz "github.com/google/gofuzz"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
@@ -40,7 +42,7 @@ func TestFuzzProcessBlockHeader_10000(t *testing.T) {
|
||||
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
_, err = ProcessBlockHeader(context.Background(), s, block)
|
||||
_, err = ProcessBlockHeader(context.Background(), s, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
_ = err
|
||||
}
|
||||
}
|
||||
@@ -71,14 +73,14 @@ func TestFuzzverifyDepositDataSigningRoot_10000(t *testing.T) {
|
||||
|
||||
func TestFuzzProcessEth1DataInBlock_10000(t *testing.T) {
|
||||
fuzzer := fuzz.NewWithSeed(0)
|
||||
b := ð.SignedBeaconBlock{}
|
||||
e := ð.Eth1Data{}
|
||||
state := &stateV0.BeaconState{}
|
||||
for i := 0; i < 10000; i++ {
|
||||
fuzzer.Fuzz(state)
|
||||
fuzzer.Fuzz(b)
|
||||
s, err := ProcessEth1DataInBlock(context.Background(), state, b)
|
||||
fuzzer.Fuzz(e)
|
||||
s, err := ProcessEth1DataInBlock(context.Background(), state, e)
|
||||
if err != nil && s != nil {
|
||||
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and block: %v", s, err, state, b)
|
||||
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and eth1data: %v", s, err, state, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +125,7 @@ func TestFuzzProcessBlockHeaderNoVerify_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(block)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
_, err = ProcessBlockHeaderNoVerify(s, block)
|
||||
_, err = ProcessBlockHeaderNoVerify(s, block.Slot, block.ProposerIndex, block.ParentRoot, []byte{})
|
||||
_ = err
|
||||
}
|
||||
}
|
||||
@@ -138,7 +140,7 @@ func TestFuzzProcessRandao_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(b)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessRandao(context.Background(), s, b)
|
||||
r, err := ProcessRandao(context.Background(), s, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
}
|
||||
@@ -155,7 +157,7 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(blockBody)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessRandaoNoVerify(s, blockBody)
|
||||
r, err := ProcessRandaoNoVerify(s, blockBody.RandaoReveal)
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, blockBody)
|
||||
}
|
||||
@@ -165,16 +167,16 @@ func TestFuzzProcessRandaoNoVerify_10000(t *testing.T) {
|
||||
func TestFuzzProcessProposerSlashings_10000(t *testing.T) {
|
||||
fuzzer := fuzz.NewWithSeed(0)
|
||||
state := &pb.BeaconState{}
|
||||
b := ð.SignedBeaconBlock{}
|
||||
p := ð.ProposerSlashing{}
|
||||
ctx := context.Background()
|
||||
for i := 0; i < 10000; i++ {
|
||||
fuzzer.Fuzz(state)
|
||||
fuzzer.Fuzz(b)
|
||||
fuzzer.Fuzz(p)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessProposerSlashings(ctx, s, b)
|
||||
r, err := ProcessProposerSlashings(ctx, s, []*eth.ProposerSlashing{p}, v.SlashValidator)
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and slashing: %v", r, err, state, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,16 +198,16 @@ func TestFuzzVerifyProposerSlashing_10000(t *testing.T) {
|
||||
func TestFuzzProcessAttesterSlashings_10000(t *testing.T) {
|
||||
fuzzer := fuzz.NewWithSeed(0)
|
||||
state := &pb.BeaconState{}
|
||||
b := ð.SignedBeaconBlock{}
|
||||
a := ð.AttesterSlashing{}
|
||||
ctx := context.Background()
|
||||
for i := 0; i < 10000; i++ {
|
||||
fuzzer.Fuzz(state)
|
||||
fuzzer.Fuzz(b)
|
||||
fuzzer.Fuzz(a)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessAttesterSlashings(ctx, s, b)
|
||||
r, err := ProcessAttesterSlashings(ctx, s, []*eth.AttesterSlashing{a}, v.SlashValidator)
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and slashing: %v", r, err, state, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +259,7 @@ func TestFuzzProcessAttestations_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(b)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessAttestations(ctx, s, b)
|
||||
r, err := ProcessAttestations(ctx, s, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
}
|
||||
@@ -274,7 +276,7 @@ func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(b)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessAttestationsNoVerifySignature(ctx, s, b)
|
||||
r, err := ProcessAttestationsNoVerifySignature(ctx, s, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
}
|
||||
@@ -399,16 +401,16 @@ func TestFuzzverifyDeposit_10000(t *testing.T) {
|
||||
func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
|
||||
fuzzer := fuzz.NewWithSeed(0)
|
||||
state := &pb.BeaconState{}
|
||||
b := ð.SignedBeaconBlock{}
|
||||
e := ð.SignedVoluntaryExit{}
|
||||
ctx := context.Background()
|
||||
for i := 0; i < 10000; i++ {
|
||||
fuzzer.Fuzz(state)
|
||||
fuzzer.Fuzz(b)
|
||||
fuzzer.Fuzz(e)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessVoluntaryExits(ctx, s, b)
|
||||
r, err := ProcessVoluntaryExits(ctx, s, []*eth.SignedVoluntaryExit{e})
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and exit: %v", r, err, state, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -416,15 +418,15 @@ func TestFuzzProcessVoluntaryExits_10000(t *testing.T) {
|
||||
func TestFuzzProcessVoluntaryExitsNoVerify_10000(t *testing.T) {
|
||||
fuzzer := fuzz.NewWithSeed(0)
|
||||
state := &pb.BeaconState{}
|
||||
b := ð.SignedBeaconBlock{}
|
||||
e := ð.SignedVoluntaryExit{}
|
||||
for i := 0; i < 10000; i++ {
|
||||
fuzzer.Fuzz(state)
|
||||
fuzzer.Fuzz(b)
|
||||
fuzzer.Fuzz(e)
|
||||
s, err := stateV0.InitializeFromProtoUnsafe(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessVoluntaryExits(context.Background(), s, b)
|
||||
r, err := ProcessVoluntaryExits(context.Background(), s, []*eth.SignedVoluntaryExit{e})
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
@@ -90,7 +91,7 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b)
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
if !newRegistry[expectedSlashedVal].Slashed {
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/depositutil"
|
||||
@@ -28,6 +28,15 @@ func ProcessPreGenesisDeposits(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not process deposit")
|
||||
}
|
||||
beaconState, err = activateValidatorWithEffectiveBalance(beaconState, deposits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return beaconState, nil
|
||||
}
|
||||
|
||||
// This updates validator's effective balance, and if it's above MaxEffectiveBalance, validator becomes active in genesis.
|
||||
func activateValidatorWithEffectiveBalance(beaconState iface.BeaconState, deposits []*ethpb.Deposit) (iface.BeaconState, error) {
|
||||
for _, deposit := range deposits {
|
||||
pubkey := deposit.Data.PublicKey
|
||||
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubkey))
|
||||
@@ -69,25 +78,18 @@ func ProcessDeposits(
|
||||
beaconState iface.BeaconState,
|
||||
deposits []*ethpb.Deposit,
|
||||
) (iface.BeaconState, error) {
|
||||
var err error
|
||||
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Attempt to verify all deposit signatures at once, if this fails then fall back to processing
|
||||
// individual deposits with signature verification enabled.
|
||||
var verifySignature bool
|
||||
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
|
||||
log.WithError(err).Debug("Failed to verify deposit data, verifying signatures individually")
|
||||
verifySignature = true
|
||||
batchVerified, err := batchVerifyDepositsSignatures(ctx, deposits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, deposit := range deposits {
|
||||
if deposit == nil || deposit.Data == nil {
|
||||
return nil, errors.New("got a nil deposit in block")
|
||||
}
|
||||
beaconState, err = ProcessDeposit(beaconState, deposit, verifySignature)
|
||||
beaconState, err = ProcessDeposit(beaconState, deposit, batchVerified)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not process deposit from %#x", bytesutil.Trunc(deposit.Data.PublicKey))
|
||||
}
|
||||
@@ -95,6 +97,21 @@ func ProcessDeposits(
|
||||
return beaconState, nil
|
||||
}
|
||||
|
||||
func batchVerifyDepositsSignatures(ctx context.Context, deposits []*ethpb.Deposit) (bool, error) {
|
||||
var err error
|
||||
domain, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
verified := false
|
||||
if err := verifyDepositDataWithDomain(ctx, deposits, domain); err != nil {
|
||||
log.WithError(err).Debug("Failed to batch verify deposits signatures, will try individual verify")
|
||||
verified = true
|
||||
}
|
||||
return verified, nil
|
||||
}
|
||||
|
||||
// ProcessDeposit takes in a deposit object and inserts it
|
||||
// into the registry as a new validator or balance change.
|
||||
//
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -19,24 +19,20 @@ import (
|
||||
// def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||
// state.eth1_data_votes.append(body.eth1_data)
|
||||
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
|
||||
// state.latest_eth1_data = body.eth1_data
|
||||
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, b *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
|
||||
block := b.Block
|
||||
if beaconState == nil {
|
||||
// state.eth1_data = body.eth1_data
|
||||
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, eth1Data *ethpb.Eth1Data) (iface.BeaconState, error) {
|
||||
if beaconState == nil || beaconState.IsNil() {
|
||||
return nil, errors.New("nil state")
|
||||
}
|
||||
if block == nil || block.Body == nil {
|
||||
return nil, errors.New("nil block or block withought body")
|
||||
}
|
||||
if err := beaconState.AppendEth1DataVotes(block.Body.Eth1Data); err != nil {
|
||||
if err := beaconState.AppendEth1DataVotes(eth1Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hasSupport, err := Eth1DataHasEnoughSupport(beaconState, block.Body.Eth1Data)
|
||||
hasSupport, err := Eth1DataHasEnoughSupport(beaconState, eth1Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasSupport {
|
||||
if err := beaconState.SetEth1Data(block.Body.Eth1Data); err != nil {
|
||||
if err := beaconState.SetEth1Data(eth1Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -62,7 +58,7 @@ func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
|
||||
// votes to see if they match the eth1data.
|
||||
func Eth1DataHasEnoughSupport(beaconState iface.ReadOnlyBeaconState, data *ethpb.Eth1Data) (bool, error) {
|
||||
voteCount := uint64(0)
|
||||
data = stateV0.CopyETH1Data(data)
|
||||
data = copyutil.CopyETH1Data(data)
|
||||
|
||||
for _, vote := range beaconState.Eth1DataVotes() {
|
||||
if AreEth1DataEqual(vote, data) {
|
||||
|
||||
@@ -5,17 +5,18 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func FakeDeposits(n uint64) []*ethpb.Eth1Data {
|
||||
@@ -178,7 +179,7 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
|
||||
period := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod)))
|
||||
var ok bool
|
||||
for i := uint64(0); i < period; i++ {
|
||||
processedState, err := blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b)
|
||||
processedState, err := blocks.ProcessEth1DataInBlock(context.Background(), beaconState, b.Block.Body.Eth1Data)
|
||||
require.NoError(t, err)
|
||||
beaconState, ok = processedState.(*stateV0.BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
@@ -188,7 +189,7 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
|
||||
if len(newETH1DataVotes) <= 1 {
|
||||
t.Error("Expected new ETH1 data votes to have length > 1")
|
||||
}
|
||||
if !proto.Equal(beaconState.Eth1Data(), stateV0.CopyETH1Data(b.Block.Body.Eth1Data)) {
|
||||
if !proto.Equal(beaconState.Eth1Data(), copyutil.CopyETH1Data(b.Block.Body.Eth1Data)) {
|
||||
t.Errorf(
|
||||
"Expected latest eth1 data to have been set to %v, received %v",
|
||||
b.Block.Body.Eth1Data,
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -26,35 +26,28 @@ var ValidatorCannotExitYetMsg = "validator has not been active long enough to ex
|
||||
// should exit the state's validator registry.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
|
||||
// """
|
||||
// Process ``VoluntaryExit`` operation.
|
||||
// """
|
||||
// validator = state.validator_registry[exit.validator_index]
|
||||
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
|
||||
// voluntary_exit = signed_voluntary_exit.message
|
||||
// validator = state.validators[voluntary_exit.validator_index]
|
||||
// # Verify the validator is active
|
||||
// assert is_active_validator(validator, get_current_epoch(state))
|
||||
// # Verify the validator has not yet exited
|
||||
// # Verify exit has not been initiated
|
||||
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
|
||||
// # Exits must specify an epoch when they become valid; they are not valid before then
|
||||
// assert get_current_epoch(state) >= exit.epoch
|
||||
// assert get_current_epoch(state) >= voluntary_exit.epoch
|
||||
// # Verify the validator has been active long enough
|
||||
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
|
||||
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
|
||||
// # Verify signature
|
||||
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
|
||||
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
|
||||
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
|
||||
// signing_root = compute_signing_root(voluntary_exit, domain)
|
||||
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
|
||||
// # Initiate exit
|
||||
// initiate_validator_exit(state, exit.validator_index)
|
||||
// initiate_validator_exit(state, voluntary_exit.validator_index)
|
||||
func ProcessVoluntaryExits(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
exits []*ethpb.SignedVoluntaryExit,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
exits := body.VoluntaryExits
|
||||
for idx, exit := range exits {
|
||||
if exit == nil || exit.Exit == nil {
|
||||
return nil, errors.New("nil voluntary exit in block body")
|
||||
@@ -77,22 +70,23 @@ func ProcessVoluntaryExits(
|
||||
// VerifyExitAndSignature implements the spec defined validation for voluntary exits.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
|
||||
// """
|
||||
// Process ``VoluntaryExit`` operation.
|
||||
// """
|
||||
// validator = state.validator_registry[exit.validator_index]
|
||||
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
|
||||
// voluntary_exit = signed_voluntary_exit.message
|
||||
// validator = state.validators[voluntary_exit.validator_index]
|
||||
// # Verify the validator is active
|
||||
// assert is_active_validator(validator, get_current_epoch(state))
|
||||
// # Verify the validator has not yet exited
|
||||
// # Verify exit has not been initiated
|
||||
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
|
||||
// # Exits must specify an epoch when they become valid; they are not valid before then
|
||||
// assert get_current_epoch(state) >= exit.epoch
|
||||
// assert get_current_epoch(state) >= voluntary_exit.epoch
|
||||
// # Verify the validator has been active long enough
|
||||
// assert get_current_epoch(state) >= validator.activation_epoch + PERSISTENT_COMMITTEE_PERIOD
|
||||
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
|
||||
// # Verify signature
|
||||
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
|
||||
// assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
|
||||
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
|
||||
// signing_root = compute_signing_root(voluntary_exit, domain)
|
||||
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
|
||||
// # Initiate exit
|
||||
// initiate_validator_exit(state, voluntary_exit.validator_index)
|
||||
func VerifyExitAndSignature(
|
||||
validator iface.ReadOnlyValidator,
|
||||
currentSlot types.Slot,
|
||||
@@ -122,19 +116,23 @@ func VerifyExitAndSignature(
|
||||
// verifyExitConditions implements the spec defined validation for voluntary exits(excluding signatures).
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
|
||||
// """
|
||||
// Process ``VoluntaryExit`` operation.
|
||||
// """
|
||||
// validator = state.validator_registry[exit.validator_index]
|
||||
// def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
|
||||
// voluntary_exit = signed_voluntary_exit.message
|
||||
// validator = state.validators[voluntary_exit.validator_index]
|
||||
// # Verify the validator is active
|
||||
// assert is_active_validator(validator, get_current_epoch(state))
|
||||
// # Verify the validator has not yet exited
|
||||
// # Verify exit has not been initiated
|
||||
// assert validator.exit_epoch == FAR_FUTURE_EPOCH
|
||||
// # Exits must specify an epoch when they become valid; they are not valid before then
|
||||
// assert get_current_epoch(state) >= exit.epoch
|
||||
// assert get_current_epoch(state) >= voluntary_exit.epoch
|
||||
// # Verify the validator has been active long enough
|
||||
// assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
|
||||
// # Verify signature
|
||||
// domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
|
||||
// signing_root = compute_signing_root(voluntary_exit, domain)
|
||||
// assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
|
||||
// # Initiate exit
|
||||
// initiate_validator_exit(state, voluntary_exit.validator_index)
|
||||
func verifyExitConditions(validator iface.ReadOnlyValidator, currentSlot types.Slot, exit *ethpb.VoluntaryExit) error {
|
||||
currentEpoch := helpers.SlotToEpoch(currentSlot)
|
||||
// Verify the validator is active.
|
||||
@@ -152,7 +150,7 @@ func verifyExitConditions(validator iface.ReadOnlyValidator, currentSlot types.S
|
||||
// Verify the validator has been active long enough.
|
||||
if currentEpoch < validator.ActivationEpoch()+params.BeaconConfig().ShardCommitteePeriod {
|
||||
return fmt.Errorf(
|
||||
"%s: %d of %d epochs. Validator will be eligible for exit at epoch %d.",
|
||||
"%s: %d of %d epochs. Validator will be eligible for exit at epoch %d",
|
||||
ValidatorCannotExitYetMsg,
|
||||
currentEpoch-validator.ActivationEpoch(),
|
||||
params.BeaconConfig().ShardCommitteePeriod,
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
@@ -44,7 +44,7 @@ func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := "validator has not been active long enough to exit"
|
||||
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
|
||||
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) {
|
||||
}
|
||||
|
||||
want := "validator with index 0 has already submitted an exit, which will take place at epoch: 10"
|
||||
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b)
|
||||
_, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b)
|
||||
newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits)
|
||||
require.NoError(t, err, "Could not process exits")
|
||||
newRegistry := newState.Validators()
|
||||
if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -19,35 +20,43 @@ import (
|
||||
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||
// # Verify that the slots match
|
||||
// assert block.slot == state.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// # Verify that the block is newer than latest block header
|
||||
// assert block.slot > state.latest_block_header.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// assert block.proposer_index == get_beacon_proposer_index(state)
|
||||
// # Verify that the parent matches
|
||||
// assert block.parent_root == hash_tree_root(state.latest_block_header)
|
||||
// # Save current block as the new latest block
|
||||
// # Cache current block as the new latest block
|
||||
// state.latest_block_header = BeaconBlockHeader(
|
||||
// slot=block.slot,
|
||||
// proposer_index=block.proposer_index,
|
||||
// parent_root=block.parent_root,
|
||||
// # state_root: zeroed, overwritten in the next `process_slot` call
|
||||
// state_root=Bytes32(), # Overwritten in the next process_slot call
|
||||
// body_root=hash_tree_root(block.body),
|
||||
// # signature is always zeroed
|
||||
// )
|
||||
//
|
||||
// # Verify proposer is not slashed
|
||||
// proposer = state.validators[get_beacon_proposer_index(state)]
|
||||
// proposer = state.validators[block.proposer_index]
|
||||
// assert not proposer.slashed
|
||||
// # Verify proposer signature
|
||||
// assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
|
||||
func ProcessBlockHeader(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
block *ethpb.SignedBeaconBlock,
|
||||
block interfaces.SignedBeaconBlock,
|
||||
) (iface.BeaconState, error) {
|
||||
beaconState, err := ProcessBlockHeaderNoVerify(beaconState, block.Block)
|
||||
if err := helpers.VerifyNilBeaconBlock(block); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyRoot, err := block.Block().Body().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
beaconState, err = ProcessBlockHeaderNoVerify(beaconState, block.Block().Slot(), block.Block().ProposerIndex(), block.Block().ParentRoot(), bodyRoot[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify proposer signature.
|
||||
if err := VerifyBlockSignature(beaconState, block); err != nil {
|
||||
if err := VerifyBlockSignature(beaconState, block.Block().ProposerIndex(), block.Signature(), block.Block().HashTreeRoot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -64,51 +73,52 @@ func ProcessBlockHeader(
|
||||
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||
// # Verify that the slots match
|
||||
// assert block.slot == state.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// # Verify that the block is newer than latest block header
|
||||
// assert block.slot > state.latest_block_header.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// assert block.proposer_index == get_beacon_proposer_index(state)
|
||||
// # Verify that the parent matches
|
||||
// assert block.parent_root == hash_tree_root(state.latest_block_header)
|
||||
// # Save current block as the new latest block
|
||||
// # Cache current block as the new latest block
|
||||
// state.latest_block_header = BeaconBlockHeader(
|
||||
// slot=block.slot,
|
||||
// proposer_index=block.proposer_index,
|
||||
// parent_root=block.parent_root,
|
||||
// # state_root: zeroed, overwritten in the next `process_slot` call
|
||||
// state_root=Bytes32(), # Overwritten in the next process_slot call
|
||||
// body_root=hash_tree_root(block.body),
|
||||
// # signature is always zeroed
|
||||
// )
|
||||
//
|
||||
// # Verify proposer is not slashed
|
||||
// proposer = state.validators[get_beacon_proposer_index(state)]
|
||||
// proposer = state.validators[block.proposer_index]
|
||||
// assert not proposer.slashed
|
||||
func ProcessBlockHeaderNoVerify(
|
||||
beaconState iface.BeaconState,
|
||||
block *ethpb.BeaconBlock,
|
||||
slot types.Slot, proposerIndex types.ValidatorIndex,
|
||||
parentRoot, bodyRoot []byte,
|
||||
) (iface.BeaconState, error) {
|
||||
if block == nil {
|
||||
return nil, errors.New("nil block")
|
||||
}
|
||||
if beaconState.Slot() != block.Slot {
|
||||
return nil, fmt.Errorf("state slot: %d is different than block slot: %d", beaconState.Slot(), block.Slot)
|
||||
if beaconState.Slot() != slot {
|
||||
return nil, fmt.Errorf("state slot: %d is different than block slot: %d", beaconState.Slot(), slot)
|
||||
}
|
||||
idx, err := helpers.BeaconProposerIndex(beaconState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if block.ProposerIndex != idx {
|
||||
return nil, fmt.Errorf("proposer index: %d is different than calculated: %d", block.ProposerIndex, idx)
|
||||
if proposerIndex != idx {
|
||||
return nil, fmt.Errorf("proposer index: %d is different than calculated: %d", proposerIndex, idx)
|
||||
}
|
||||
parentHeader := beaconState.LatestBlockHeader()
|
||||
if parentHeader.Slot >= block.Slot {
|
||||
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", block.Slot, parentHeader.Slot)
|
||||
if parentHeader.Slot >= slot {
|
||||
return nil, fmt.Errorf("block.Slot %d must be greater than state.LatestBlockHeader.Slot %d", slot, parentHeader.Slot)
|
||||
}
|
||||
parentRoot, err := parentHeader.HashTreeRoot()
|
||||
parentHeaderRoot, err := parentHeader.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !bytes.Equal(block.ParentRoot, parentRoot[:]) {
|
||||
if !bytes.Equal(parentRoot, parentHeaderRoot[:]) {
|
||||
return nil, fmt.Errorf(
|
||||
"parent root %#x does not match the latest block header signing root in state %#x",
|
||||
block.ParentRoot, parentRoot)
|
||||
parentRoot, parentHeaderRoot[:])
|
||||
}
|
||||
|
||||
proposer, err := beaconState.ValidatorAtIndexReadOnly(idx)
|
||||
@@ -119,16 +129,12 @@ func ProcessBlockHeaderNoVerify(
|
||||
return nil, fmt.Errorf("proposer at index %d was previously slashed", idx)
|
||||
}
|
||||
|
||||
bodyRoot, err := block.Body.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := beaconState.SetLatestBlockHeader(ðpb.BeaconBlockHeader{
|
||||
Slot: block.Slot,
|
||||
ProposerIndex: block.ProposerIndex,
|
||||
ParentRoot: block.ParentRoot,
|
||||
Slot: slot,
|
||||
ProposerIndex: proposerIndex,
|
||||
ParentRoot: parentRoot,
|
||||
StateRoot: params.BeaconConfig().ZeroHash[:],
|
||||
BodyRoot: bodyRoot[:],
|
||||
BodyRoot: bodyRoot,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,18 +5,19 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -65,7 +66,7 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
|
||||
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
assert.ErrorContains(t, "block.Slot 10 must be greater than state.LatestBlockHeader.Slot 10", err)
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ func TestProcessBlockHeader_WrongProposerSig(t *testing.T) {
|
||||
block.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx+1])
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, block)
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
want := "signature did not verify"
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
@@ -125,18 +126,15 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
|
||||
blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, &sszBytes, params.BeaconConfig().DomainBeaconProposer, priv)
|
||||
require.NoError(t, err)
|
||||
validators[5896].PublicKey = priv.PublicKey().Marshal()
|
||||
block := ðpb.SignedBeaconBlock{
|
||||
block := testutil.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{
|
||||
Block: ðpb.BeaconBlock{
|
||||
Slot: 1,
|
||||
Body: ðpb.BeaconBlockBody{
|
||||
RandaoReveal: []byte{'A', 'B', 'C'},
|
||||
},
|
||||
Slot: 1,
|
||||
ParentRoot: lbhsr[:],
|
||||
},
|
||||
Signature: blockSig,
|
||||
}
|
||||
})
|
||||
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
want := "is different than block slot"
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
@@ -175,7 +173,7 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
|
||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{'A'}, 32)
|
||||
block.Signature = blockSig
|
||||
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
want := "does not match"
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
@@ -217,7 +215,7 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
|
||||
block.Block.ParentRoot = parentRoot[:]
|
||||
block.Signature = blockSig
|
||||
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
|
||||
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
want := "was previously slashed"
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
@@ -266,7 +264,7 @@ func TestProcessBlockHeader_OK(t *testing.T) {
|
||||
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
|
||||
require.NoError(t, err)
|
||||
|
||||
newState, err := blocks.ProcessBlockHeader(context.Background(), state, block)
|
||||
newState, err := blocks.ProcessBlockHeader(context.Background(), state, interfaces.WrappedPhase0SignedBeaconBlock(block))
|
||||
require.NoError(t, err, "Failed to process block header got")
|
||||
var zeroHash [32]byte
|
||||
nsh := newState.LatestBlockHeader()
|
||||
@@ -321,7 +319,7 @@ func TestBlockSignatureSet_OK(t *testing.T) {
|
||||
validators[proposerIdx].PublicKey = priv.PublicKey().Marshal()
|
||||
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
|
||||
require.NoError(t, err)
|
||||
set, err := blocks.BlockSignatureSet(state, block)
|
||||
set, err := blocks.BlockSignatureSet(state, block.Block.ProposerIndex, block.Signature, block.Block.HashTreeRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
verified, err := set.Verify()
|
||||
|
||||
@@ -4,58 +4,57 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type slashValidatorFunc func(iface.BeaconState, types.ValidatorIndex) (iface.BeaconState, error)
|
||||
|
||||
// ProcessProposerSlashings is one of the operations performed
|
||||
// on each processed beacon block to slash proposers based on
|
||||
// slashing conditions if any slashable events occurred.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSlashing) -> None:
|
||||
// """
|
||||
// Process ``ProposerSlashing`` operation.
|
||||
// """
|
||||
// proposer = state.validator_registry[proposer_slashing.proposer_index]
|
||||
// # Verify slots match
|
||||
// assert proposer_slashing.header_1.slot == proposer_slashing.header_2.slot
|
||||
// # But the headers are different
|
||||
// assert proposer_slashing.header_1 != proposer_slashing.header_2
|
||||
// # Check proposer is slashable
|
||||
// assert is_slashable_validator(proposer, get_current_epoch(state))
|
||||
// # Signatures are valid
|
||||
// for header in (proposer_slashing.header_1, proposer_slashing.header_2):
|
||||
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
|
||||
// assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)
|
||||
// header_1 = proposer_slashing.signed_header_1.message
|
||||
// header_2 = proposer_slashing.signed_header_2.message
|
||||
//
|
||||
// slash_validator(state, proposer_slashing.proposer_index)
|
||||
// # Verify header slots match
|
||||
// assert header_1.slot == header_2.slot
|
||||
// # Verify header proposer indices match
|
||||
// assert header_1.proposer_index == header_2.proposer_index
|
||||
// # Verify the headers are different
|
||||
// assert header_1 != header_2
|
||||
// # Verify the proposer is slashable
|
||||
// proposer = state.validators[header_1.proposer_index]
|
||||
// assert is_slashable_validator(proposer, get_current_epoch(state))
|
||||
// # Verify signatures
|
||||
// for signed_header in (proposer_slashing.signed_header_1, proposer_slashing.signed_header_2):
|
||||
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(signed_header.message.slot))
|
||||
// signing_root = compute_signing_root(signed_header.message, domain)
|
||||
// assert bls.Verify(proposer.pubkey, signing_root, signed_header.signature)
|
||||
//
|
||||
// slash_validator(state, header_1.proposer_index)
|
||||
func ProcessProposerSlashings(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
slashings []*ethpb.ProposerSlashing,
|
||||
slashFunc slashValidatorFunc,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
var err error
|
||||
for idx, slashing := range body.ProposerSlashings {
|
||||
for idx, slashing := range slashings {
|
||||
if slashing == nil {
|
||||
return nil, errors.New("nil proposer slashings in block body")
|
||||
}
|
||||
if err = VerifyProposerSlashing(beaconState, slashing); err != nil {
|
||||
return nil, errors.Wrapf(err, "could not verify proposer slashing %d", idx)
|
||||
}
|
||||
beaconState, err = v.SlashValidator(
|
||||
beaconState, slashing.Header_1.Header.ProposerIndex,
|
||||
)
|
||||
beaconState, err = slashFunc(beaconState, slashing.Header_1.Header.ProposerIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not slash proposer index %d", slashing.Header_1.Header.ProposerIndex)
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
@@ -49,7 +50,7 @@ func TestProcessProposerSlashings_UnmatchedHeaderSlots(t *testing.T) {
|
||||
},
|
||||
}
|
||||
want := "mismatched header slots"
|
||||
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
|
||||
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b.Block.Body.ProposerSlashings, v.SlashValidator)
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ func TestProcessProposerSlashings_SameHeaders(t *testing.T) {
|
||||
},
|
||||
}
|
||||
want := "expected slashing headers to differ"
|
||||
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
|
||||
_, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, b.Block.Body.ProposerSlashings, v.SlashValidator)
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
|
||||
"validator with key %#x is not slashable",
|
||||
bytesutil.ToBytes48(beaconState.Validators()[0].PublicKey),
|
||||
)
|
||||
_, err = blocks.ProcessProposerSlashings(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessProposerSlashings(context.Background(), beaconState, b.Block.Body.ProposerSlashings, v.SlashValidator)
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ func TestProcessProposerSlashings_AppliesCorrectStatus(t *testing.T) {
|
||||
block := testutil.NewBeaconBlock()
|
||||
block.Block.Body.ProposerSlashings = slashings
|
||||
|
||||
newState, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block)
|
||||
newState, err := blocks.ProcessProposerSlashings(context.Background(), beaconState, block.Block.Body.ProposerSlashings, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
|
||||
newStateVals := newState.Validators()
|
||||
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
@@ -28,21 +28,21 @@ import (
|
||||
func ProcessRandao(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
b interfaces.SignedBeaconBlock,
|
||||
) (iface.BeaconState, error) {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := b.Block.Body
|
||||
body := b.Block().Body()
|
||||
buf, proposerPub, domain, err := randaoSigningData(beaconState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := verifySignature(buf, proposerPub, body.RandaoReveal, domain); err != nil {
|
||||
if err := verifySignature(buf, proposerPub, body.RandaoReveal(), domain); err != nil {
|
||||
return nil, errors.Wrap(err, "could not verify block randao")
|
||||
}
|
||||
|
||||
beaconState, err = ProcessRandaoNoVerify(beaconState, body)
|
||||
beaconState, err = ProcessRandaoNoVerify(beaconState, body.RandaoReveal())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not process randao")
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func ProcessRandao(
|
||||
// )
|
||||
func ProcessRandaoNoVerify(
|
||||
beaconState iface.BeaconState,
|
||||
body *ethpb.BeaconBlockBody,
|
||||
randaoReveal []byte,
|
||||
) (iface.BeaconState, error) {
|
||||
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
|
||||
// If block randao passed verification, we XOR the state's latest randao mix with the block's
|
||||
@@ -70,7 +70,7 @@ func ProcessRandaoNoVerify(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockRandaoReveal := hashutil.Hash(body.RandaoReveal)
|
||||
blockRandaoReveal := hashutil.Hash(randaoReveal)
|
||||
if len(blockRandaoReveal) != len(latestMixSlice) {
|
||||
return nil, errors.New("blockRandaoReveal length doesnt match latestMixSlice length")
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
@@ -38,7 +39,7 @@ func TestProcessRandao_IncorrectProposerFailsVerification(t *testing.T) {
|
||||
}
|
||||
|
||||
want := "block randao: signature did not verify"
|
||||
_, err = blocks.ProcessRandao(context.Background(), beaconState, b)
|
||||
_, err = blocks.ProcessRandao(context.Background(), beaconState, interfaces.WrappedPhase0SignedBeaconBlock(b))
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ func TestProcessRandao_SignatureVerifiesAndUpdatesLatestStateMixes(t *testing.T)
|
||||
newState, err := blocks.ProcessRandao(
|
||||
context.Background(),
|
||||
beaconState,
|
||||
b,
|
||||
interfaces.WrappedPhase0SignedBeaconBlock(b),
|
||||
)
|
||||
require.NoError(t, err, "Unexpected error processing block randao")
|
||||
currentEpoch := helpers.CurrentEpoch(beaconState)
|
||||
@@ -80,7 +81,7 @@ func TestRandaoSignatureSet_OK(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
set, err := blocks.RandaoSignatureSet(beaconState, block.Body)
|
||||
set, err := blocks.RandaoSignatureSet(beaconState, block.Body.RandaoReveal)
|
||||
require.NoError(t, err)
|
||||
verified, err := set.Verify()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/bls"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
@@ -60,45 +60,51 @@ func verifySignature(signedData, pub, signature, domain []byte) error {
|
||||
}
|
||||
|
||||
// VerifyBlockSignature verifies the proposer signature of a beacon block.
|
||||
func VerifyBlockSignature(beaconState iface.ReadOnlyBeaconState, block *ethpb.SignedBeaconBlock) error {
|
||||
func VerifyBlockSignature(beaconState iface.ReadOnlyBeaconState,
|
||||
proposerIndex types.ValidatorIndex,
|
||||
sig []byte,
|
||||
rootFunc func() ([32]byte, error)) error {
|
||||
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
|
||||
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconProposer, beaconState.GenesisValidatorRoot())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proposer, err := beaconState.ValidatorAtIndex(block.Block.ProposerIndex)
|
||||
proposer, err := beaconState.ValidatorAtIndex(proposerIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proposerPubKey := proposer.PublicKey
|
||||
return helpers.VerifyBlockSigningRoot(block.Block, proposerPubKey, block.Signature, domain)
|
||||
return helpers.VerifyBlockSigningRoot(proposerPubKey, sig, domain, rootFunc)
|
||||
}
|
||||
|
||||
// BlockSignatureSet retrieves the block signature set from the provided block and its corresponding state.
|
||||
func BlockSignatureSet(beaconState iface.ReadOnlyBeaconState, block *ethpb.SignedBeaconBlock) (*bls.SignatureSet, error) {
|
||||
func BlockSignatureSet(beaconState iface.ReadOnlyBeaconState,
|
||||
proposerIndex types.ValidatorIndex,
|
||||
sig []byte,
|
||||
rootFunc func() ([32]byte, error)) (*bls.SignatureSet, error) {
|
||||
currentEpoch := helpers.SlotToEpoch(beaconState.Slot())
|
||||
domain, err := helpers.Domain(beaconState.Fork(), currentEpoch, params.BeaconConfig().DomainBeaconProposer, beaconState.GenesisValidatorRoot())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proposer, err := beaconState.ValidatorAtIndex(block.Block.ProposerIndex)
|
||||
proposer, err := beaconState.ValidatorAtIndex(proposerIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proposerPubKey := proposer.PublicKey
|
||||
return helpers.BlockSignatureSet(block.Block, proposerPubKey, block.Signature, domain)
|
||||
return helpers.BlockSignatureSet(proposerPubKey, sig, domain, rootFunc)
|
||||
}
|
||||
|
||||
// RandaoSignatureSet retrieves the relevant randao specific signature set object
|
||||
// from a block and its corresponding state.
|
||||
func RandaoSignatureSet(beaconState iface.ReadOnlyBeaconState,
|
||||
body *ethpb.BeaconBlockBody,
|
||||
reveal []byte,
|
||||
) (*bls.SignatureSet, error) {
|
||||
buf, proposerPub, domain, err := randaoSigningData(beaconState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
set, err := signatureSet(buf, proposerPub, body.RandaoReveal, domain)
|
||||
set, err := signatureSet(buf, proposerPub, reveal, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +206,7 @@ func AttestationSignatureSet(ctx context.Context, beaconState iface.ReadOnlyBeac
|
||||
set := bls.NewSet()
|
||||
|
||||
// Check attestations from before the fork.
|
||||
if fork.Epoch > 0 { // Check to prevent underflow.
|
||||
if fork.Epoch > 0 && len(preForkAtts) > 0 { // Check to prevent underflow and there is valid attestations to create sig set.
|
||||
prevDomain, err := helpers.Domain(fork, fork.Epoch-1, dt, gvr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -209,22 +215,30 @@ func AttestationSignatureSet(ctx context.Context, beaconState iface.ReadOnlyBeac
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
set.Join(aSet)
|
||||
if aSet != nil {
|
||||
set.Join(aSet)
|
||||
}
|
||||
} else if len(preForkAtts) > 0 {
|
||||
// This is a sanity check that preForkAtts were not ignored when fork.Epoch == 0. This
|
||||
// condition is not possible, but it doesn't hurt to check anyway.
|
||||
return nil, errors.New("some attestations were not verified from previous fork before genesis")
|
||||
}
|
||||
|
||||
// Then check attestations from after the fork.
|
||||
currDomain, err := helpers.Domain(fork, fork.Epoch, dt, gvr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if len(postForkAtts) > 0 {
|
||||
// Then check attestations from after the fork.
|
||||
currDomain, err := helpers.Domain(fork, fork.Epoch, dt, gvr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aSet, err := createAttestationSignatureSet(ctx, beaconState, postForkAtts, currDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if aSet != nil {
|
||||
return set.Join(aSet), nil
|
||||
}
|
||||
}
|
||||
|
||||
aSet, err := createAttestationSignatureSet(ctx, beaconState, postForkAtts, currDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return set.Join(aSet), nil
|
||||
return set, nil
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["block_processing_test.yaml.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks/spectest",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
)
|
||||
|
||||
test_suite(
|
||||
name = "go_default_test",
|
||||
tags = ["spectest"],
|
||||
tests = [
|
||||
":go_mainnet_test",
|
||||
# Minimal tests must be run with --define ssz=minimal
|
||||
#":go_minimal_test",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_mainnet_test",
|
||||
size = "medium",
|
||||
srcs = glob(
|
||||
["*_test.go"],
|
||||
exclude = ["*_minimal_test.go"],
|
||||
),
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@eth2_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
shard_count = 4,
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/state/stateutils:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
# Requires --define ssz=minimal
|
||||
go_test(
|
||||
name = "go_minimal_test",
|
||||
size = "small",
|
||||
srcs = glob(
|
||||
["*_test.go"],
|
||||
exclude = ["*_mainnet_test.go"],
|
||||
),
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@eth2_spec_tests_minimal//:test_data",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = [
|
||||
"manual",
|
||||
"minimal",
|
||||
"spectest",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/state/stateutils:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/params/spectest:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAttestationMainnet(t *testing.T) {
|
||||
runAttestationTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAttestationMinimal(t *testing.T) {
|
||||
runAttestationTest(t, "minimal")
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func runAttestationTest(t *testing.T, config string) {
|
||||
require.NoError(t, spectest.SetConfig(t, config))
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attestation/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
attestationFile, err := testutil.BazelFileBytes(folderPath, "attestation.ssz")
|
||||
require.NoError(t, err)
|
||||
att := ðpb.Attestation{}
|
||||
require.NoError(t, att.UnmarshalSSZ(attestationFile), "Failed to unmarshal")
|
||||
|
||||
body := ðpb.BeaconBlockBody{Attestations: []*ethpb.Attestation{att}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttestations)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAttesterSlashingMainnet(t *testing.T) {
|
||||
runAttesterSlashingTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAttesterSlashingMinimal(t *testing.T) {
|
||||
runAttesterSlashingTest(t, "minimal")
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func runAttesterSlashingTest(t *testing.T, config string) {
|
||||
require.NoError(t, spectest.SetConfig(t, config))
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/attester_slashing/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
attSlashingFile, err := testutil.BazelFileBytes(folderPath, "attester_slashing.ssz")
|
||||
require.NoError(t, err)
|
||||
attSlashing := ðpb.AttesterSlashing{}
|
||||
require.NoError(t, attSlashing.UnmarshalSSZ(attSlashingFile), "Failed to unmarshal")
|
||||
|
||||
body := ðpb.BeaconBlockBody{AttesterSlashings: []*ethpb.AttesterSlashing{attSlashing}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessAttesterSlashings)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBlockHeaderMainnet(t *testing.T) {
|
||||
runBlockHeaderTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBlockHeaderMinimal(t *testing.T) {
|
||||
runBlockHeaderTest(t, "minimal")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBlockProcessingMainnetYaml(t *testing.T) {
|
||||
runBlockProcessingTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBlockProcessingMinimalYaml(t *testing.T) {
|
||||
runBlockProcessingTest(t, "minimal")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDepositMainnetYaml(t *testing.T) {
|
||||
runDepositTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDepositMinimalYaml(t *testing.T) {
|
||||
runDepositTest(t, "minimal")
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func runDepositTest(t *testing.T, config string) {
|
||||
require.NoError(t, spectest.SetConfig(t, config))
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/deposit/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
depositFile, err := testutil.BazelFileBytes(folderPath, "deposit.ssz")
|
||||
require.NoError(t, err)
|
||||
deposit := ðpb.Deposit{}
|
||||
require.NoError(t, deposit.UnmarshalSSZ(depositFile), "Failed to unmarshal")
|
||||
|
||||
body := ðpb.BeaconBlockBody{Deposits: []*ethpb.Deposit{deposit}}
|
||||
processDepositsFunc := func(ctx context.Context, s iface.BeaconState, b *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
|
||||
return blocks.ProcessDeposits(ctx, s, b.Block.Body.Deposits)
|
||||
}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, processDepositsFunc)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProposerSlashingMainnet(t *testing.T) {
|
||||
runProposerSlashingTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProposerSlashingMinimal(t *testing.T) {
|
||||
runProposerSlashingTest(t, "minimal")
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func runProposerSlashingTest(t *testing.T, config string) {
|
||||
require.NoError(t, spectest.SetConfig(t, config))
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/proposer_slashing/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
proposerSlashingFile, err := testutil.BazelFileBytes(folderPath, "proposer_slashing.ssz")
|
||||
require.NoError(t, err)
|
||||
proposerSlashing := ðpb.ProposerSlashing{}
|
||||
require.NoError(t, proposerSlashing.UnmarshalSSZ(proposerSlashingFile), "Failed to unmarshal")
|
||||
|
||||
body := ðpb.BeaconBlockBody{ProposerSlashings: []*ethpb.ProposerSlashing{proposerSlashing}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessProposerSlashings)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVoluntaryExitMainnet(t *testing.T) {
|
||||
runVoluntaryExitTest(t, "mainnet")
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVoluntaryExitMinimal(t *testing.T) {
|
||||
runVoluntaryExitTest(t, "minimal")
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package spectest
|
||||
|
||||
import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/shared/params/spectest"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func runVoluntaryExitTest(t *testing.T, config string) {
|
||||
require.NoError(t, spectest.SetConfig(t, config))
|
||||
|
||||
testFolders, testsFolderPath := testutil.TestFolders(t, config, "operations/voluntary_exit/pyspec_tests")
|
||||
for _, folder := range testFolders {
|
||||
t.Run(folder.Name(), func(t *testing.T) {
|
||||
folderPath := path.Join(testsFolderPath, folder.Name())
|
||||
exitFile, err := testutil.BazelFileBytes(folderPath, "voluntary_exit.ssz")
|
||||
require.NoError(t, err)
|
||||
voluntaryExit := ðpb.SignedVoluntaryExit{}
|
||||
require.NoError(t, voluntaryExit.UnmarshalSSZ(exitFile), "Failed to unmarshal")
|
||||
|
||||
body := ðpb.BeaconBlockBody{VoluntaryExits: []*ethpb.SignedVoluntaryExit{voluntaryExit}}
|
||||
testutil.RunBlockOperationTest(t, folderPath, body, blocks.ProcessVoluntaryExits)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,23 @@ go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["epoch_processing.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
visibility = [
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//spectest:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/copyutil:go_default_library",
|
||||
"//shared/featureconfig:go_default_library",
|
||||
"//shared/mathutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,14 +38,14 @@ go_test(
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_google_gofuzz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -10,13 +10,14 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/copyutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
||||
"github.com/prysmaticlabs/prysm/shared/mathutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
@@ -28,8 +29,13 @@ type sortableIndices struct {
|
||||
validators []*ethpb.Validator
|
||||
}
|
||||
|
||||
func (s sortableIndices) Len() int { return len(s.indices) }
|
||||
// Len is the number of elements in the collection.
|
||||
func (s sortableIndices) Len() int { return len(s.indices) }
|
||||
|
||||
// Swap swaps the elements with indexes i and j.
|
||||
func (s sortableIndices) Swap(i, j int) { s.indices[i], s.indices[j] = s.indices[j], s.indices[i] }
|
||||
|
||||
// Less reports whether the element with index i must sort before the element with index j.
|
||||
func (s sortableIndices) Less(i, j int) bool {
|
||||
if s.validators[s.indices[i]].ActivationEligibilityEpoch == s.validators[s.indices[j]].ActivationEligibilityEpoch {
|
||||
return s.indices[i] < s.indices[j]
|
||||
@@ -44,7 +50,11 @@ func (s sortableIndices) Less(i, j int) bool {
|
||||
// need to get attesting balance from attestations.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_attesting_balance(state: BeaconState, attestations: List[PendingAttestation]) -> Gwei:
|
||||
// def get_attesting_balance(state: BeaconState, attestations: Sequence[PendingAttestation]) -> Gwei:
|
||||
// """
|
||||
// Return the combined effective balance of the set of unslashed validators participating in ``attestations``.
|
||||
// Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
||||
// """
|
||||
// return get_total_balance(state, get_unslashed_attesting_indices(state, attestations))
|
||||
func AttestingBalance(state iface.ReadOnlyBeaconState, atts []*pb.PendingAttestation) (uint64, error) {
|
||||
indices, err := UnslashedAttestingIndices(state, atts)
|
||||
@@ -153,7 +163,7 @@ func ProcessRegistryUpdates(state iface.BeaconState) (iface.BeaconState, error)
|
||||
// for index, validator in enumerate(state.validators):
|
||||
// if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
|
||||
// increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow
|
||||
// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
|
||||
// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
|
||||
// penalty = penalty_numerator // total_balance * increment
|
||||
// decrease_balance(state, ValidatorIndex(index), penalty)
|
||||
func ProcessSlashings(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
@@ -192,47 +202,15 @@ func ProcessSlashings(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
return state, err
|
||||
}
|
||||
|
||||
// ProcessFinalUpdates processes the final updates during epoch processing.
|
||||
// ProcessEth1DataReset processes updates to ETH1 data votes during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_final_updates(state: BeaconState) -> None:
|
||||
// current_epoch = get_current_epoch(state)
|
||||
// next_epoch = Epoch(current_epoch + 1)
|
||||
// def process_eth1_data_reset(state: BeaconState) -> None:
|
||||
// next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
// # Reset eth1 data votes
|
||||
// if next_epoch % EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
|
||||
// state.eth1_data_votes = []
|
||||
// # Update effective balances with hysteresis
|
||||
// for index, validator in enumerate(state.validators):
|
||||
// balance = state.balances[index]
|
||||
// HYSTERESIS_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT
|
||||
// DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
|
||||
// UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
||||
// if (
|
||||
// balance + DOWNWARD_THRESHOLD < validator.effective_balance
|
||||
// or validator.effective_balance + UPWARD_THRESHOLD < balance
|
||||
// ):
|
||||
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
||||
// index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY)
|
||||
// index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR
|
||||
// indices_list = List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, index_epoch))
|
||||
// state.active_index_roots[index_root_position] = hash_tree_root(indices_list)
|
||||
// # Set committees root
|
||||
// committee_root_position = next_epoch % EPOCHS_PER_HISTORICAL_VECTOR
|
||||
// state.compact_committees_roots[committee_root_position] = get_compact_committees_root(state, next_epoch)
|
||||
// # Reset slashings
|
||||
// state.slashings[next_epoch % EPOCHS_PER_SLASHINGS_VECTOR] = Gwei(0)
|
||||
// # Set randao mix
|
||||
// state.randao_mixes[next_epoch % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, current_epoch)
|
||||
// # Set historical root accumulator
|
||||
// if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0:
|
||||
// historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots)
|
||||
// state.historical_roots.append(hash_tree_root(historical_batch))
|
||||
// # Update start shard
|
||||
// state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT)
|
||||
// # Rotate current/previous epoch attestations
|
||||
// state.previous_epoch_attestations = state.current_epoch_attestations
|
||||
// state.current_epoch_attestations = []
|
||||
func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
func ProcessEth1DataReset(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
nextEpoch := currentEpoch + 1
|
||||
|
||||
@@ -243,6 +221,25 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessEffectiveBalanceUpdates processes effective balance updates during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_effective_balance_updates(state: BeaconState) -> None:
|
||||
// # Update effective balances with hysteresis
|
||||
// for index, validator in enumerate(state.validators):
|
||||
// balance = state.balances[index]
|
||||
// HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT)
|
||||
// DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
|
||||
// UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
||||
// if (
|
||||
// balance + DOWNWARD_THRESHOLD < validator.effective_balance
|
||||
// or validator.effective_balance + UPWARD_THRESHOLD < balance
|
||||
// ):
|
||||
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
||||
func ProcessEffectiveBalanceUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
effBalanceInc := params.BeaconConfig().EffectiveBalanceIncrement
|
||||
maxEffBalance := params.BeaconConfig().MaxEffectiveBalance
|
||||
hysteresisInc := effBalanceInc / params.BeaconConfig().HysteresisQuotient
|
||||
@@ -261,7 +258,7 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
balance := bals[idx]
|
||||
|
||||
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
|
||||
newVal := stateV0.CopyValidator(val)
|
||||
newVal := copyutil.CopyValidator(val)
|
||||
newVal.EffectiveBalance = maxEffBalance
|
||||
if newVal.EffectiveBalance > balance-balance%effBalanceInc {
|
||||
newVal.EffectiveBalance = balance - balance%effBalanceInc
|
||||
@@ -271,10 +268,50 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
return false, val, nil
|
||||
}
|
||||
|
||||
if featureconfig.Get().EnableOptimizedBalanceUpdate {
|
||||
validatorFunc = func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
|
||||
if val == nil {
|
||||
return false, nil, fmt.Errorf("validator %d is nil in state", idx)
|
||||
}
|
||||
if idx >= len(bals) {
|
||||
return false, nil, fmt.Errorf("validator index exceeds validator length in state %d >= %d", idx, len(state.Balances()))
|
||||
}
|
||||
balance := bals[idx]
|
||||
|
||||
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
|
||||
effectiveBal := maxEffBalance
|
||||
if effectiveBal > balance-balance%effBalanceInc {
|
||||
effectiveBal = balance - balance%effBalanceInc
|
||||
}
|
||||
if effectiveBal != val.EffectiveBalance {
|
||||
newVal := copyutil.CopyValidator(val)
|
||||
newVal.EffectiveBalance = effectiveBal
|
||||
return true, newVal, nil
|
||||
}
|
||||
return false, val, nil
|
||||
}
|
||||
return false, val, nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := state.ApplyToEveryValidator(validatorFunc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessSlashingsReset processes the total slashing balances updates during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_slashings_reset(state: BeaconState) -> None:
|
||||
// next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
// # Reset slashings
|
||||
// state.slashings[next_epoch % EPOCHS_PER_SLASHINGS_VECTOR] = Gwei(0)
|
||||
func ProcessSlashingsReset(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
nextEpoch := currentEpoch + 1
|
||||
|
||||
// Set total slashed balances.
|
||||
slashedExitLength := params.BeaconConfig().EpochsPerSlashingsVector
|
||||
slashedEpoch := nextEpoch % slashedExitLength
|
||||
@@ -290,6 +327,21 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessRandaoMixesReset processes the final updates to RANDAO mix during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_randao_mixes_reset(state: BeaconState) -> None:
|
||||
// current_epoch = get_current_epoch(state)
|
||||
// next_epoch = Epoch(current_epoch + 1)
|
||||
// # Set randao mix
|
||||
// state.randao_mixes[next_epoch % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, current_epoch)
|
||||
func ProcessRandaoMixesReset(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
nextEpoch := currentEpoch + 1
|
||||
|
||||
// Set RANDAO mix.
|
||||
randaoMixLength := params.BeaconConfig().EpochsPerHistoricalVector
|
||||
if uint64(state.RandaoMixesLength()) != uint64(randaoMixLength) {
|
||||
@@ -307,6 +359,22 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessHistoricalRootsUpdate processes the updates to historical root accumulator during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_historical_roots_update(state: BeaconState) -> None:
|
||||
// # Set historical root accumulator
|
||||
// next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
// if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0:
|
||||
// historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots)
|
||||
// state.historical_roots.append(hash_tree_root(historical_batch))
|
||||
func ProcessHistoricalRootsUpdate(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
nextEpoch := currentEpoch + 1
|
||||
|
||||
// Set historical root accumulator.
|
||||
epochsPerHistoricalRoot := params.BeaconConfig().SlotsPerHistoricalRoot.DivSlot(params.BeaconConfig().SlotsPerEpoch)
|
||||
if nextEpoch.Mod(uint64(epochsPerHistoricalRoot)) == 0 {
|
||||
@@ -323,13 +391,66 @@ func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Rotate current and previous epoch attestations.
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessParticipationRecordUpdates rotates current/previous epoch attestations during epoch processing.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_participation_record_updates(state: BeaconState) -> None:
|
||||
// # Rotate current/previous epoch attestations
|
||||
// state.previous_epoch_attestations = state.current_epoch_attestations
|
||||
// state.current_epoch_attestations = []
|
||||
func ProcessParticipationRecordUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
if err := state.RotateAttestations(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessFinalUpdates processes the final updates during epoch processing.
|
||||
func ProcessFinalUpdates(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
var err error
|
||||
|
||||
// Reset ETH1 data votes.
|
||||
state, err = ProcessEth1DataReset(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update effective balances with hysteresis.
|
||||
state, err = ProcessEffectiveBalanceUpdates(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set total slashed balances.
|
||||
state, err = ProcessSlashingsReset(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set RANDAO mix.
|
||||
state, err = ProcessRandaoMixesReset(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set historical root accumulator.
|
||||
state, err = ProcessHistoricalRootsUpdate(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Rotate current and previous epoch attestations.
|
||||
state, err = ProcessParticipationRecordUpdates(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// UnslashedAttestingIndices returns all the attesting indices from a list of attestations,
|
||||
// it sorts the indices and filters out the slashed ones.
|
||||
//
|
||||
@@ -385,9 +506,9 @@ func UnslashedAttestingIndices(state iface.ReadOnlyBeaconState, atts []*pb.Pendi
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
|
||||
// total_balance = get_total_active_balance(state)
|
||||
// effective_balance = state.validator_registry[index].effective_balance
|
||||
// return effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH
|
||||
// total_balance = get_total_active_balance(state)
|
||||
// effective_balance = state.validators[index].effective_balance
|
||||
// return Gwei(effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH)
|
||||
func BaseReward(state iface.ReadOnlyBeaconState, index types.ValidatorIndex) (uint64, error) {
|
||||
totalBalance, err := helpers.TotalActiveBalance(state)
|
||||
if err != nil {
|
||||
|
||||
@@ -4,19 +4,19 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
|
||||
|
||||
@@ -12,18 +12,21 @@ go_library(
|
||||
"type.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
visibility = [
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//spectest:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/state/interface:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/mathutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/traceutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -43,15 +46,15 @@ go_test(
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/state/stateV0:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/attestationutil:go_default_library",
|
||||
"//shared/mathutil:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/attestationutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
|
||||
@@ -2,18 +2,47 @@ package precompute
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
// ProcessJustificationAndFinalizationPreCompute processes justification and finalization during
|
||||
// epoch processing. This is where a beacon node can justify and finalize a new epoch.
|
||||
// Note: this is an optimized version by passing in precomputed total and attesting balances.
|
||||
// def process_justification_and_finalization(state: BeaconState) -> None:
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_justification_and_finalization(state: BeaconState) -> None:
|
||||
// # Initial FFG checkpoint values have a `0x00` stub for `root`.
|
||||
// # Skip FFG updates in the first two epochs to avoid corner cases that might result in modifying this stub.
|
||||
// if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
||||
// return
|
||||
// previous_attestations = get_matching_target_attestations(state, get_previous_epoch(state))
|
||||
// current_attestations = get_matching_target_attestations(state, get_current_epoch(state))
|
||||
// total_active_balance = get_total_active_balance(state)
|
||||
// previous_target_balance = get_attesting_balance(state, previous_attestations)
|
||||
// current_target_balance = get_attesting_balance(state, current_attestations)
|
||||
// weigh_justification_and_finalization(state, total_active_balance, previous_target_balance, current_target_balance)
|
||||
func ProcessJustificationAndFinalizationPreCompute(state iface.BeaconState, pBal *Balance) (iface.BeaconState, error) {
|
||||
canProcessSlot, err := helpers.StartSlot(2 /*epoch*/)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if state.Slot() <= canProcessSlot {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
return weighJustificationAndFinalization(state, pBal.ActiveCurrentEpoch, pBal.PrevEpochTargetAttested, pBal.CurrentEpochTargetAttested)
|
||||
}
|
||||
|
||||
// weighJustificationAndFinalization processes justification and finalization during
|
||||
// epoch processing. This is where a beacon node can justify and finalize a new epoch.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def weigh_justification_and_finalization(state: BeaconState,
|
||||
// total_active_balance: Gwei,
|
||||
// previous_epoch_target_balance: Gwei,
|
||||
// current_epoch_target_balance: Gwei) -> None:
|
||||
// previous_epoch = get_previous_epoch(state)
|
||||
// current_epoch = get_current_epoch(state)
|
||||
// old_previous_justified_checkpoint = state.previous_justified_checkpoint
|
||||
@@ -21,15 +50,13 @@ import (
|
||||
//
|
||||
// # Process justifications
|
||||
// state.previous_justified_checkpoint = state.current_justified_checkpoint
|
||||
// state.justification_bits[1:] = state.justification_bits[:-1]
|
||||
// state.justification_bits[1:] = state.justification_bits[:JUSTIFICATION_BITS_LENGTH - 1]
|
||||
// state.justification_bits[0] = 0b0
|
||||
// matching_target_attestations = get_matching_target_attestations(state, previous_epoch) # Previous epoch
|
||||
// if get_attesting_balance(state, matching_target_attestations) * 3 >= get_total_active_balance(state) * 2:
|
||||
// if previous_epoch_target_balance * 3 >= total_active_balance * 2:
|
||||
// state.current_justified_checkpoint = Checkpoint(epoch=previous_epoch,
|
||||
// root=get_block_root(state, previous_epoch))
|
||||
// state.justification_bits[1] = 0b1
|
||||
// matching_target_attestations = get_matching_target_attestations(state, current_epoch) # Current epoch
|
||||
// if get_attesting_balance(state, matching_target_attestations) * 3 >= get_total_active_balance(state) * 2:
|
||||
// if current_epoch_target_balance * 3 >= total_active_balance * 2:
|
||||
// state.current_justified_checkpoint = Checkpoint(epoch=current_epoch,
|
||||
// root=get_block_root(state, current_epoch))
|
||||
// state.justification_bits[0] = 0b1
|
||||
@@ -48,15 +75,8 @@ import (
|
||||
// # The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
|
||||
// if all(bits[0:2]) and old_current_justified_checkpoint.epoch + 1 == current_epoch:
|
||||
// state.finalized_checkpoint = old_current_justified_checkpoint
|
||||
func ProcessJustificationAndFinalizationPreCompute(state iface.BeaconState, pBal *Balance) (iface.BeaconState, error) {
|
||||
canProcessSlot, err := helpers.StartSlot(2 /*epoch*/)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if state.Slot() <= canProcessSlot {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func weighJustificationAndFinalization(state iface.BeaconState,
|
||||
totalActiveBalance, prevEpochTargetBalance, currEpochTargetBalance uint64) (iface.BeaconState, error) {
|
||||
prevEpoch := helpers.PrevEpoch(state)
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
oldPrevJustifiedCheckpoint := state.PreviousJustifiedCheckpoint()
|
||||
@@ -76,7 +96,7 @@ func ProcessJustificationAndFinalizationPreCompute(state iface.BeaconState, pBal
|
||||
// We will use that paradigm here for consistency with the godoc spec definition.
|
||||
|
||||
// If 2/3 or more of total balance attested in the previous epoch.
|
||||
if 3*pBal.PrevEpochTargetAttested >= 2*pBal.ActiveCurrentEpoch {
|
||||
if 3*prevEpochTargetBalance >= 2*totalActiveBalance {
|
||||
blockRoot, err := helpers.BlockRoot(state, prevEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root for previous epoch %d", prevEpoch)
|
||||
@@ -92,7 +112,7 @@ func ProcessJustificationAndFinalizationPreCompute(state iface.BeaconState, pBal
|
||||
}
|
||||
|
||||
// If 2/3 or more of the total balance attested in the current epoch.
|
||||
if 3*pBal.CurrentEpochTargetAttested >= 2*pBal.ActiveCurrentEpoch {
|
||||
if 3*currEpochTargetBalance >= 2*totalActiveBalance {
|
||||
blockRoot, err := helpers.BlockRoot(state, currentEpoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get block root for current epoch %d", prevEpoch)
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user