Compare commits

...

33 Commits

Author SHA1 Message Date
Preston Van Loon
57a63f37f7 Update holesky config for new genesis (#12919)
* Update holesky config with new genesis. See https://github.com/eth-clients/holesky/pull/73

* Update bootnodes

* Update bootnodes

* Use latest commit

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-23 16:09:28 +00:00
Preston Van Loon
9a2c2470c6 db: Log a warning if the genesis state is smaller than 1Kb (#12897)
* Add warning with a small genesis state

* 1<<10 is 1Kb

* Add genesis state loading with hash information

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-23 15:29:15 +00:00
james-prysm
723f73795f Deneb: blob sidecar events (#12928)
* adding in deneb blob event triggers

* fixing linting

* kasey's feedback

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-22 21:54:10 +00:00
Raul Jordan
6454081577 Amend Bug Report Template Requirements (#12937)
* requirements

* amend

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-22 20:26:24 +00:00
Potuz
489b34a01f Use headstate when requesting current epochs (#12940)
* Use headstate when requesting current epochs

* gazelle

* review requests
2023-09-22 19:48:24 +00:00
Radosław Kapka
e22258caa9 HTTP validator APIs (#12887)
* GetValidators in progress

* in progress

* completed implementation of GetValidators + some tests

* typo

* completed tests for GetValidators

* GetValidator

* GetValidatorBalances

* register

* more tests and e2e fix

* middleware cleanup

* remove struct

* handle all ignored

* test fixes

* more test fixes

* even more test fixes

* remove unused structs

* docs

* fix validator count test

* build fix

* add length checks

* lint fix

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2023-09-21 18:16:59 +00:00
Radosław Kapka
3bc9ac37f6 Add Content-Type header to VC POST requests (#12942) 2023-09-21 17:21:06 +00:00
Nishant Das
7247b8bd3c Fix Unhandled Error (#12938)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-21 16:23:56 +00:00
Potuz
e2591f7c5b Do not cache proposer ID on GetProposerDuties (#12939) 2023-09-21 15:22:41 +00:00
Radosław Kapka
b40729f6c0 Return correct root from GetBlockHeader (#12935)
* Return correct root from `GetBlockHeader`

* variable rename
2023-09-21 12:02:14 +00:00
Nishant Das
b7cb5c81be fix it (#12932) 2023-09-21 11:40:03 +08:00
Radosław Kapka
e76aedf1ae HTTP API: GetLiveness and GetBlockHeader (#12916)
* GetLiveness

* GetBlockHeader

* simplify request objects

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-20 19:06:11 +00:00
terencechain
0e5d299d02 Remove unused pending blobs queue (#12913)
* Remove pending blobs queue

* Fix tests

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2023-09-20 17:00:01 +00:00
Radosław Kapka
14f040de48 GetFinalityCheckpoints and GetGenesis HTTP endpoints (#12902)
* GetFinalityCheckpoints and GetGenesis

* bzl

* remove unused func

* use const as base path

* bring back headers

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-19 17:53:45 +00:00
terencechain
1a1a30591e Handle Specific Blob Retrieval Error in DB (#12889)
* log db blob by root error

* Add comments
2023-09-19 15:29:13 +00:00
terencechain
3070878d59 Add Blind Blob Sidecar Signing in Validator Client (#12922)
* Add validator signing blind blob sidecar

* Fix tests

* Refactor

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-19 00:36:42 +00:00
terencechain
f59307358e Copy kzg commitments when using builder block (#12923) 2023-09-18 23:54:20 +00:00
Potuz
ef1f5e6dbe remove unused function (#12920)
* remove unused function

* remove the actual method

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-18 21:30:30 +00:00
terencechain
a22ca3fecb Update geth to v1.13.1 (#12911)
* Update geth

* Fix builder

* Update geth to v1.13.1.

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-18 21:12:07 +00:00
james-prysm
14ce051668 Deneb builder fix (#12921)
* fixing conversion for deneb

* updating unit test to catch this in the future

* gaz
2023-09-18 20:34:28 +00:00
terencechain
998a493ee2 Fix builder blind block namings (#12910)
* Fix builder blind block namings

* Fix

* Fix tests

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2023-09-18 15:32:10 +00:00
Nishant Das
398f44bb53 fix it (#12917) 2023-09-18 22:30:34 +08:00
Nishant Das
4098b3a1d2 fix it (#12915) 2023-09-18 21:42:54 +08:00
Radosław Kapka
d8e6d2cb2e Fix proposer duties sorting (#12909)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-16 14:11:57 +00:00
Potuz
6b915bab26 Dont process blocks twice (#12905)
* keep track of block being synced

* gazelle

* use maps

* shutup deepsource

* change godoc

* Radek's review

* Do not process block twice if it's already being processed

* add unit test
2023-09-15 20:11:02 +00:00
Potuz
dd73f762ec keep track of block being synced (#12903)
* keep track of block being synced

* gazelle

* use maps

* shutup deepsource

* change godoc

* Radek's review
2023-09-15 17:13:13 +00:00
anukul
4d120b53ae HTTP Beacon API: /eth/v1/beacon/headers (#12817)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2023-09-15 12:05:35 +02:00
terencechain
4d6b3252ae Fix deneb builder bid HTR (#12906)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-15 00:14:03 +00:00
terencechain
9bb81537c8 feat: add blob arrival gossip metric (#12888)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-14 21:35:18 +00:00
Potuz
0fdf63b565 default to 7 seconds for first aggregation (#12876)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-14 17:46:28 +00:00
Sammy Rosso
bd85b0e4e1 Update bug report template (#12891)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2023-09-14 16:41:49 +00:00
terencechain
d1562bab53 Update blind blobs bundle max commitment size (#12901)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-09-14 14:21:56 +00:00
terencechain
1e29877406 don't save blob sidecar syncing to head if 0 (#12892) 2023-09-14 13:17:49 +00:00
160 changed files with 5531 additions and 7436 deletions

View File

@@ -1,59 +0,0 @@
---
name: "\U0001F41EBug report"
about: Report a bug or problem with running Prysm
---
<!--💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎
Hellooo! 😄
To help us tend to your issue faster, please search our currently open issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎💎-->
# 🐞 Bug Report
### Description
<!-- ✍️--> A clear and concise description of the problem...
### Has this worked before in a previous version?
<!-- Did this behavior use to work in the previous version? -->
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
## 🔬 Minimal Reproduction
<!--
Please let us know how we can reproduce this issue. Include the exact method you used to run Prysm along with any flags used in your beacon chain and/or validator. Make sure you don't upload any confidential files or private keys.
-->
## 🔥 Error
<pre><code>
<!-- If the issue is accompanied by an error, please share the error logs with us below. If you have a lot of logs, place make a paste bin with your logs and share the link with us here: -->
<!-- ✍️-->
</code></pre>
## 🌍 Your Environment
**Operating System:**
<pre>
<code>
</code>
</pre>
**What version of Prysm are you running? (Which release)**
<pre>
<code>
</code>
</pre>
**Anything else relevant (validator index / public key)?**

66
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: 🐞 Bug report
description: Report a bug or problem with running Prysm
labels: ["Bug"]
body:
- type: markdown
attributes:
value: |
To help us tend to your issue faster, please search our currently open issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
- type: textarea
id: what-happened
attributes:
label: Describe the bug
description: |
A clear and concise description of the problem...
validations:
required: true
- type: textarea
id: previous-version
attributes:
label: Has this worked before in a previous version?
description: Did this behavior use to work in the previous version?
render: text
- type: textarea
id: reproduction-steps
attributes:
label: 🔬 Minimal Reproduction
description: |
Please let us know how we can reproduce this issue.
Include the exact method you used to run Prysm along with any flags used in your beacon chain and/or validator.
Make sure you don't upload any confidential files or private keys.
placeholder: |
Steps to reproduce:
1. Start '...'
2. Then '...'
3. Check '...'
4. See error
- type: textarea
id: errors
attributes:
label: Error
description: |
If the issue is accompanied by an error, please share the error logs with us below.
If you have a lot of logs, place make a paste bin with your logs and share the link with us here:
render: text
- type: dropdown
id: platform
attributes:
label: Platform(s)
description: What platform(s) did this occur on?
multiple: true
options:
- Linux (x86)
- Linux (ARM)
- Mac (Intel)
- Mac (Apple Silicon)
- Windows (x86)
- Windows (ARM)
- type: input
attributes:
label: What version of Prysm are you running? (Which release)
description: You can check your Prysm version by running your beacon node or validator with the `--version` flag.
- type: textarea
attributes:
label: Anything else relevant (validator index / public key)?

View File

@@ -323,9 +323,9 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "4116c8acb54eb3ca28cc4dc9bc688e08e25da91d70ed1f2622f02d3c33eba922",
strip_prefix = "holesky-76057d57ab1f585519ecb606a9e5f7780e925a37",
url = "https://github.com/eth-clients/holesky/archive/76057d57ab1f585519ecb606a9e5f7780e925a37.tar.gz", # Aug 27, 2023
sha256 = "9f66d8d5644982d3d0d2e3d2b9ebe77a5f96638a5d7fcd715599c32818195cb3",
strip_prefix = "holesky-ea39b9006210848e13f28d92e12a30548cecd41d",
url = "https://github.com/eth-clients/holesky/archive/ea39b9006210848e13f28d92e12a30548cecd41d.tar.gz", # 2023-09-21
)
http_archive(

View File

@@ -11,6 +11,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v4/api/client/builder",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/rpc/eth/shared:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types:go_default_library",
"//consensus-types/blocks:go_default_library",
@@ -41,6 +42,7 @@ go_test(
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = [
"//beacon-chain/rpc/eth/shared:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
@@ -54,5 +56,6 @@ go_test(
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

View File

@@ -13,6 +13,7 @@ import (
"text/template"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -365,8 +366,10 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS
if err != nil {
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
}
b := &ethpb.SignedBlindedBeaconBlockAndBlobsDeneb{Block: psb, Blobs: blobs}
b, err := shared.SignedBlindedBeaconBlockContentsDenebFromConsensus(&ethpb.SignedBlindedBeaconBlockAndBlobsDeneb{SignedBlindedBlock: psb, SignedBlindedBlobSidecars: blobs})
if err != nil {
return nil, nil, errors.Wrapf(err, "could not convert SignedBlindedBeaconBlockContentsDeneb to json marshalable type")
}
body, err := json.Marshal(b)
if err != nil {
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockDeneb value body in SubmitBlindedBlockDeneb")

View File

@@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
@@ -23,6 +24,7 @@ import (
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
log "github.com/sirupsen/logrus"
)
type roundtrip func(*http.Request) (*http.Response, error)
@@ -397,10 +399,18 @@ func TestSubmitBlindedBlock(t *testing.T) {
assert.Equal(t, uint64(1), withdrawals[0].Amount)
})
t.Run("deneb", func(t *testing.T) {
test := testSignedBlindedBeaconBlockAndBlobsDeneb(t)
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "deneb", r.Header.Get("Eth-Consensus-Version"))
var req shared.SignedBlindedBeaconBlockContentsDeneb
err := json.NewDecoder(r.Body).Decode(&req)
require.NoError(t, err)
block, err := req.SignedBlindedBlock.ToConsensus()
require.NoError(t, err)
require.DeepEqual(t, block, test.SignedBlindedBlock)
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayloadDeneb)),
@@ -412,11 +422,11 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc: hc,
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
}
test := testSignedBlindedBeaconBlockAndBlobsDeneb(t)
sbb, err := blocks.NewSignedBeaconBlock(test.Block)
sbb, err := blocks.NewSignedBeaconBlock(test.SignedBlindedBlock)
require.NoError(t, err)
ep, blobBundle, err := c.SubmitBlindedBlock(ctx, sbb, test.Blobs)
ep, blobBundle, err := c.SubmitBlindedBlock(ctx, sbb, test.SignedBlindedBlobSidecars)
require.NoError(t, err)
withdrawals, err := ep.Withdrawals()
require.NoError(t, err)
@@ -744,9 +754,13 @@ func testSignedBlindedBeaconBlockCapella(t *testing.T) *eth.SignedBlindedBeaconB
}
func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedBeaconBlockAndBlobsDeneb {
basebytes, err := shared.Uint256ToSSZBytes("14074904626401341155369551180448584754667373453244490859944217516317499064576")
if err != nil {
log.Error(err)
}
return &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
SignedBlindedBlock: &eth.SignedBlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Slot: 1,
ProposerIndex: 1,
ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
@@ -758,7 +772,7 @@ func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedB
DepositCount: 1,
BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
},
Graffiti: ezDecode(t, "0xdeadbeefc0ffee"),
Graffiti: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
ProposerSlashings: []*eth.ProposerSlashing{
{
Header_1: &eth.SignedBeaconBlockHeader{
@@ -861,8 +875,8 @@ func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedB
},
},
SyncAggregate: &eth.SyncAggregate{
SyncCommitteeSignature: make([]byte, 48),
SyncCommitteeBits: bitfield.Bitvector512{0x01},
SyncCommitteeSignature: make([]byte, 96),
SyncCommitteeBits: bitfield.Bitvector512(ezDecode(t, "0x6451e9f951ebf05edc01de67e593484b672877054f055903ff0df1a1a945cf30ca26bb4d4b154f94a1bc776bcf5d0efb3603e1f9b8ee2499ccdcfe2a18cef458")),
},
ExecutionPayloadHeader: &v1.ExecutionPayloadHeaderDeneb{
ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
@@ -876,7 +890,7 @@ func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedB
GasUsed: 1,
Timestamp: 1,
ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
BaseFeePerGas: []byte(strconv.FormatUint(1, 10)),
BaseFeePerGas: basebytes,
BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
WithdrawalsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),
@@ -887,7 +901,7 @@ func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedB
},
Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"),
},
Blobs: []*eth.SignedBlindedBlobSidecar{
SignedBlindedBlobSidecars: []*eth.SignedBlindedBlobSidecar{
{
Message: &eth.BlindedBlobSidecar{
BlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"),

View File

@@ -15,6 +15,9 @@ func StartAndEndPage(pageToken string, pageSize, totalSize int) (int, int, strin
if pageToken == "" {
pageToken = "0"
}
if pageSize < 0 || totalSize < 0 {
return 0, 0, "", errors.Errorf("invalid page and total sizes provided: page size %d , total size %d", pageSize, totalSize)
}
if pageSize == 0 {
pageSize = params.BeaconConfig().DefaultPageSize
}
@@ -23,6 +26,9 @@ func StartAndEndPage(pageToken string, pageSize, totalSize int) (int, int, strin
if err != nil {
return 0, 0, "", errors.Wrap(err, "could not convert page token")
}
if token < 0 {
return 0, 0, "", errors.Errorf("invalid token value provided: %d", token)
}
// Start page can not be greater than set size.
start := token * pageSize

View File

@@ -85,3 +85,19 @@ func TestStartAndEndPage_ExceedsMaxPage(t *testing.T) {
_, _, _, err := pagination.StartAndEndPage("", 0, 0)
assert.ErrorContains(t, wanted, err)
}
func TestStartAndEndPage_InvalidPageValues(t *testing.T) {
_, _, _, err := pagination.StartAndEndPage("10", -1, 10)
assert.ErrorContains(t, "invalid page and total sizes provided", err)
_, _, _, err = pagination.StartAndEndPage("12", 10, -10)
assert.ErrorContains(t, "invalid page and total sizes provided", err)
_, _, _, err = pagination.StartAndEndPage("12", -50, -60)
assert.ErrorContains(t, "invalid page and total sizes provided", err)
}
func TestStartAndEndPage_InvalidTokenValue(t *testing.T) {
_, _, _, err := pagination.StartAndEndPage("-12", 50, 60)
assert.ErrorContains(t, "invalid token value provided", err)
}

View File

@@ -5,6 +5,7 @@ go_library(
srcs = [
"chain_info.go",
"chain_info_forkchoice.go",
"currently_syncing_block.go",
"error.go",
"execution_engine.go",
"forkchoice_update_execution.go",

View File

@@ -525,3 +525,8 @@ func (s *Service) recoverStateSummary(ctx context.Context, blockRoot [32]byte) (
}
return nil, errBlockDoesNotExist
}
// BlockBeingSynced returns whether the block with the given root is currently being synced
func (s *Service) BlockBeingSynced(root [32]byte) bool {
return s.blockBeingSynced.isSyncing(root)
}

View File

@@ -0,0 +1,27 @@
package blockchain
import "sync"
type currentlySyncingBlock struct {
sync.Mutex
roots map[[32]byte]struct{}
}
func (b *currentlySyncingBlock) set(root [32]byte) {
b.Lock()
defer b.Unlock()
b.roots[root] = struct{}{}
}
func (b *currentlySyncingBlock) unset(root [32]byte) {
b.Lock()
defer b.Unlock()
delete(b.roots, root)
}
func (b *currentlySyncingBlock) isSyncing(root [32]byte) bool {
b.Lock()
defer b.Unlock()
_, ok := b.roots[root]
return ok
}

View File

@@ -405,8 +405,13 @@ func kzgCommitmentsToVersionedHashes(body interfaces.ReadOnlyBeaconBlockBody) ([
versionedHashes := make([]common.Hash, len(commitments))
for i, commitment := range commitments {
versionedHashes[i] = sha256.Sum256(commitment)
versionedHashes[i][0] = blobCommitmentVersionKZG
versionedHashes[i] = ConvertKzgCommitmentToVersionedHash(commitment)
}
return versionedHashes, nil
}
func ConvertKzgCommitmentToVersionedHash(commitment []byte) common.Hash {
versionedHash := sha256.Sum256(commitment)
versionedHash[0] = blobCommitmentVersionKZG
return versionedHash
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
coreTime "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
forkchoicetypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/types"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v4/config/features"
@@ -558,7 +559,8 @@ func (s *Service) isDataAvailable(ctx context.Context, root [32]byte, signed int
// Read first from db in case we have the blobs
sidecars, err := s.cfg.BeaconDB.BlobSidecarsByRoot(ctx, root)
if err == nil {
switch {
case err == nil:
if len(sidecars) >= expected {
s.blobNotifiers.delete(root)
if err := kzg.IsDataAvailable(kzgCommitments, sidecars); err != nil {
@@ -567,6 +569,11 @@ func (s *Service) isDataAvailable(ctx context.Context, root [32]byte, signed int
logBlobSidecar(sidecars, t)
return nil
}
case errors.Is(err, db.ErrNotFound):
// If the blob sidecars haven't arrived yet, the subsequent code will wait for them.
// Note: The system will not exit with an error in this scenario.
default:
log.WithError(err).Error("could not get blob sidecars from DB")
}
found := map[uint64]struct{}{}

View File

@@ -36,6 +36,7 @@ type BlockReceiver interface {
ReceiveBlockBatch(ctx context.Context, blocks []blocks.ROBlock) error
HasBlock(ctx context.Context, root [32]byte) bool
RecentBlockSlot(root [32]byte) (primitives.Slot, error)
BlockBeingSynced([32]byte) bool
}
// BlobReceiver interface defines the methods of chain service for receiving new
@@ -58,6 +59,9 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
defer span.End()
receivedTime := time.Now()
s.blockBeingSynced.set(blockRoot)
defer s.blockBeingSynced.unset(blockRoot)
blockCopy, err := block.Copy()
if err != nil {
return err

View File

@@ -62,6 +62,7 @@ type Service struct {
clockWaiter startup.ClockWaiter
syncComplete chan struct{}
blobNotifiers *blobNotifierMap
blockBeingSynced *currentlySyncingBlock
}
// config options for the service.
@@ -134,6 +135,7 @@ func NewService(ctx context.Context, opts ...Option) (*Service, error) {
initSyncBlocks: make(map[[32]byte]interfaces.ReadOnlySignedBeaconBlock),
blobNotifiers: bn,
cfg: &config{ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache()},
blockBeingSynced: &currentlySyncingBlock{roots: make(map[[32]byte]struct{})},
}
for _, opt := range opts {
if err := opt(srv); err != nil {

View File

@@ -71,6 +71,7 @@ type ChainService struct {
FinalizedRoots map[[32]byte]bool
OptimisticRoots map[[32]byte]bool
BlockSlot primitives.Slot
SyncingRoot [32]byte
}
func (s *ChainService) Ancestor(ctx context.Context, root []byte, slot primitives.Slot) ([]byte, error) {
@@ -606,4 +607,9 @@ func (s *ChainService) UnrealizedJustifiedPayloadBlockHash() [32]byte {
}
// SendNewBlobEvent mocks the same method in the chain service
func (s *ChainService) SendNewBlobEvent(_ [32]byte, _ uint64) {}
func (*ChainService) SendNewBlobEvent(_ [32]byte, _ uint64) {}
// BlockBeingSynced mocks the same method in the chain service
func (c *ChainService) BlockBeingSynced(root [32]byte) bool {
return root == c.SyncingRoot
}

View File

@@ -22,6 +22,9 @@ const (
// BLSToExecutionChangeReceived is sent after a BLS to execution change object has been received from gossip or rpc.
BLSToExecutionChangeReceived
// BlobSidecarReceived is sent after a blob sidecar is received from gossip or rpc.
BlobSidecarReceived = 6
)
// UnAggregatedAttReceivedData is the data sent with UnaggregatedAttReceived events.
@@ -52,3 +55,8 @@ type SyncCommitteeContributionReceivedData struct {
type BLSToExecutionChangeReceivedData struct {
Change *ethpb.SignedBLSToExecutionChange
}
// BlobSidecarReceivedData is the data sent with BlobSidecarReceived events.
type BlobSidecarReceivedData struct {
Blob *ethpb.SignedBlobSidecar
}

View File

@@ -111,10 +111,10 @@ var blockTests = []struct {
name: "deneb blind",
newBlock: func(slot primitives.Slot, root []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
b := util.NewBlindedBeaconBlockDeneb()
b.Block.Slot = slot
b.Message.Slot = slot
if root != nil {
b.Block.ParentRoot = root
b.Block.Body.BlobKzgCommitments = [][]byte{
b.Message.ParentRoot = root
b.Message.Body.BlobKzgCommitments = [][]byte{
bytesutil.PadTo([]byte{0x05}, 48),
bytesutil.PadTo([]byte{0x06}, 48),
bytesutil.PadTo([]byte{0x07}, 48),

View File

@@ -2,6 +2,7 @@ package kv
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
@@ -45,6 +46,10 @@ func (s *Store) SaveGenesisData(ctx context.Context, genesisState state.BeaconSt
// LoadGenesis loads a genesis state from a ssz-serialized byte slice, if no genesis exists already.
func (s *Store) LoadGenesis(ctx context.Context, sb []byte) error {
if len(sb) < (1 << 10) {
log.WithField("size", fmt.Sprintf("%d bytes", len(sb))).
Warn("Genesis state is smaller than one 1Kb. This could be an empty file, git lfs metadata file, or corrupt genesis state.")
}
vu, err := detect.FromState(sb)
if err != nil {
return err

View File

@@ -477,8 +477,10 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
// Same test for block attestations
cache = NewAttCaches()
assert.NoError(t, cache.SaveBlockAttestations(tt.existing))
for _, att := range tt.existing {
require.NoError(t, cache.SaveBlockAttestation(att))
}
result, err = cache.HasAggregatedAttestation(tt.input)
require.NoError(t, err)
assert.Equal(t, tt.want, result)

View File

@@ -36,17 +36,6 @@ func (c *AttCaches) SaveBlockAttestation(att *ethpb.Attestation) error {
return nil
}
// SaveBlockAttestations saves a list of block attestations in cache.
func (c *AttCaches) SaveBlockAttestations(atts []*ethpb.Attestation) error {
for _, att := range atts {
if err := c.SaveBlockAttestation(att); err != nil {
return err
}
}
return nil
}
// BlockAttestations returns the block attestations in cache.
func (c *AttCaches) BlockAttestations() []*ethpb.Attestation {
atts := make([]*ethpb.Attestation, 0)

View File

@@ -32,7 +32,6 @@ type Pool interface {
UnaggregatedAttestationCount() int
// For attestations that were included in the block.
SaveBlockAttestation(att *ethpb.Attestation) error
SaveBlockAttestations(atts []*ethpb.Attestation) error
BlockAttestations() []*ethpb.Attestation
DeleteBlockAttestation(att *ethpb.Attestation) error
// For attestations to be passed to fork choice.

View File

@@ -94,7 +94,9 @@ func TestBatchAttestations_Multiple(t *testing.T) {
}
require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(unaggregatedAtts))
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(aggregatedAtts))
require.NoError(t, s.cfg.Pool.SaveBlockAttestations(blockAtts))
for _, att := range blockAtts {
require.NoError(t, s.cfg.Pool.SaveBlockAttestation(att))
}
require.NoError(t, s.batchForkChoiceAtts(context.Background()))
wanted, err := attaggregation.Aggregate([]*ethpb.Attestation{aggregatedAtts[0], blockAtts[0]})
@@ -148,7 +150,10 @@ func TestBatchAttestations_Single(t *testing.T) {
}
require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(unaggregatedAtts))
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(aggregatedAtts))
require.NoError(t, s.cfg.Pool.SaveBlockAttestations(blockAtts))
for _, att := range blockAtts {
require.NoError(t, s.cfg.Pool.SaveBlockAttestation(att))
}
require.NoError(t, s.batchForkChoiceAtts(context.Background()))
wanted, err := attaggregation.Aggregate(append(aggregatedAtts, unaggregatedAtts...))

View File

@@ -42,7 +42,9 @@ func TestPruneExpired_Ticker(t *testing.T) {
}
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
assert.Equal(t, 2, s.cfg.Pool.AggregatedAttestationCount())
require.NoError(t, s.cfg.Pool.SaveBlockAttestations(atts))
for _, att := range atts {
require.NoError(t, s.cfg.Pool.SaveBlockAttestation(att))
}
// Rewind back one epoch worth of time.
s.genesisTime = uint64(prysmTime.Now().Unix()) - uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
@@ -95,7 +97,9 @@ func TestPruneExpired_PruneExpiredAtts(t *testing.T) {
att4 := &ethpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1110}}
atts := []*ethpb.Attestation{att1, att2, att3, att4}
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
require.NoError(t, s.cfg.Pool.SaveBlockAttestations(atts))
for _, att := range atts {
require.NoError(t, s.cfg.Pool.SaveBlockAttestation(att))
}
// Rewind back one epoch worth of time.
s.genesisTime = uint64(prysmTime.Now().Unix()) - uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))

View File

@@ -40,28 +40,6 @@ func wrapBLSChangesArray(
return true, nil
}
// Some endpoints e.g. https://ethereum.github.io/beacon-apis/#/Validator/getAttesterDuties expect posting a top-level array of validator indices.
// We make it more proto-friendly by wrapping it in a struct with an 'Index' field.
func wrapValidatorIndicesArray(
endpoint *apimiddleware.Endpoint,
_ http.ResponseWriter,
req *http.Request,
) (apimiddleware.RunDefault, apimiddleware.ErrorJson) {
if _, ok := endpoint.PostRequest.(*ValidatorIndicesJson); ok {
indices := make([]string, 0)
if err := json.NewDecoder(req.Body).Decode(&indices); err != nil {
return false, apimiddleware.InternalServerErrorWithMessage(err, "could not decode body")
}
j := &ValidatorIndicesJson{Index: indices}
b, err := json.Marshal(j)
if err != nil {
return false, apimiddleware.InternalServerErrorWithMessage(err, "could not marshal wrapped body")
}
req.Body = io.NopCloser(bytes.NewReader(b))
}
return true, nil
}
type v1alpha1SignedPhase0Block struct {
Block *BeaconBlockJson `json:"block"` // tech debt on phase 0 called this block instead of "message"
Signature string `json:"signature" hex:"true"`

View File

@@ -19,47 +19,6 @@ import (
"github.com/prysmaticlabs/prysm/v4/time/slots"
)
func TestWrapValidatorIndicesArray(t *testing.T) {
t.Run("ok", func(t *testing.T) {
endpoint := &apimiddleware.Endpoint{
PostRequest: &ValidatorIndicesJson{},
}
unwrappedIndices := []string{"1", "2"}
unwrappedIndicesJson, err := json.Marshal(unwrappedIndices)
require.NoError(t, err)
var body bytes.Buffer
_, err = body.Write(unwrappedIndicesJson)
require.NoError(t, err)
request := httptest.NewRequest("POST", "http://foo.example", &body)
runDefault, errJson := wrapValidatorIndicesArray(endpoint, nil, request)
require.Equal(t, true, errJson == nil)
assert.Equal(t, apimiddleware.RunDefault(true), runDefault)
wrappedIndices := &ValidatorIndicesJson{}
require.NoError(t, json.NewDecoder(request.Body).Decode(wrappedIndices))
require.Equal(t, 2, len(wrappedIndices.Index), "wrong number of wrapped items")
assert.Equal(t, "1", wrappedIndices.Index[0])
assert.Equal(t, "2", wrappedIndices.Index[1])
})
t.Run("invalid_body", func(t *testing.T) {
endpoint := &apimiddleware.Endpoint{
PostRequest: &ValidatorIndicesJson{},
}
var body bytes.Buffer
_, err := body.Write([]byte("invalid"))
require.NoError(t, err)
request := httptest.NewRequest("POST", "http://foo.example", &body)
runDefault, errJson := wrapValidatorIndicesArray(endpoint, nil, request)
require.Equal(t, false, errJson == nil)
assert.Equal(t, apimiddleware.RunDefault(false), runDefault)
assert.Equal(t, true, strings.Contains(errJson.Msg(), "could not decode body"))
assert.Equal(t, http.StatusInternalServerError, errJson.StatusCode())
})
}
func TestWrapBLSChangesArray(t *testing.T) {
t.Run("ok", func(t *testing.T) {
endpoint := &apimiddleware.Endpoint{

View File

@@ -16,16 +16,9 @@ func (f *BeaconEndpointFactory) IsNil() bool {
// Paths is a collection of all valid beacon chain API paths.
func (_ *BeaconEndpointFactory) Paths() []string {
return []string{
"/eth/v1/beacon/genesis",
"/eth/v1/beacon/states/{state_id}/root",
"/eth/v1/beacon/states/{state_id}/finality_checkpoints",
"/eth/v1/beacon/states/{state_id}/validators",
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}",
"/eth/v1/beacon/states/{state_id}/validator_balances",
"/eth/v1/beacon/states/{state_id}/sync_committees",
"/eth/v1/beacon/states/{state_id}/randao",
"/eth/v1/beacon/headers",
"/eth/v1/beacon/headers/{block_id}",
"/eth/v1/beacon/blocks",
"/eth/v1/beacon/blinded_blocks",
"/eth/v1/beacon/blocks/{block_id}",
@@ -54,7 +47,6 @@ func (_ *BeaconEndpointFactory) Paths() []string {
"/eth/v1/validator/blocks/{slot}",
"/eth/v2/validator/blocks/{slot}",
"/eth/v1/validator/blinded_blocks/{slot}",
"/eth/v1/validator/liveness/{epoch}",
}
}
@@ -62,20 +54,8 @@ func (_ *BeaconEndpointFactory) Paths() []string {
func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, error) {
endpoint := apimiddleware.DefaultEndpoint()
switch path {
case "/eth/v1/beacon/genesis":
endpoint.GetResponse = &GenesisResponseJson{}
case "/eth/v1/beacon/states/{state_id}/root":
endpoint.GetResponse = &StateRootResponseJson{}
case "/eth/v1/beacon/states/{state_id}/finality_checkpoints":
endpoint.GetResponse = &StateFinalityCheckpointResponseJson{}
case "/eth/v1/beacon/states/{state_id}/validators":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "id", Hex: true}, {Name: "status", Enum: true}}
endpoint.GetResponse = &StateValidatorsResponseJson{}
case "/eth/v1/beacon/states/{state_id}/validators/{validator_id}":
endpoint.GetResponse = &StateValidatorResponseJson{}
case "/eth/v1/beacon/states/{state_id}/validator_balances":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "id", Hex: true}}
endpoint.GetResponse = &ValidatorBalancesResponseJson{}
case "/eth/v1/beacon/states/{state_id}/sync_committees":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "epoch"}}
endpoint.GetResponse = &SyncCommitteesResponseJson{}
@@ -85,11 +65,6 @@ func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, er
case "/eth/v1/beacon/states/{state_id}/randao":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "epoch"}}
endpoint.GetResponse = &RandaoResponseJson{}
case "/eth/v1/beacon/headers":
endpoint.RequestQueryParams = []apimiddleware.QueryParam{{Name: "slot"}, {Name: "parent_root", Hex: true}}
endpoint.GetResponse = &BlockHeadersResponseJson{}
case "/eth/v1/beacon/headers/{block_id}":
endpoint.GetResponse = &BlockHeaderResponseJson{}
case "/eth/v1/beacon/blocks":
endpoint.Hooks = apimiddleware.HookCollection{
OnPreDeserializeRequestBodyIntoContainer: setInitialPublishBlockPostRequest,
@@ -192,14 +167,6 @@ func (_ *BeaconEndpointFactory) Create(path string) (*apimiddleware.Endpoint, er
OnPreSerializeMiddlewareResponseIntoJson: serializeProducedBlindedBlock,
}
endpoint.CustomHandlers = []apimiddleware.CustomHandler{handleProduceBlindedBlockSSZ}
case "/eth/v1/validator/liveness/{epoch}":
endpoint.PostRequest = &ValidatorIndicesJson{}
endpoint.PostResponse = &LivenessResponseJson{}
endpoint.RequestURLLiterals = []string{"epoch"}
endpoint.Err = &NodeSyncDetailsErrorJson{}
endpoint.Hooks = apimiddleware.HookCollection{
OnPreDeserializeRequestBodyIntoContainer: wrapValidatorIndicesArray,
}
default:
return nil, errors.New("invalid path")
}

View File

@@ -12,16 +12,6 @@ import (
// Requests and responses.
//----------------
type GenesisResponseJson struct {
Data *GenesisResponse_GenesisJson `json:"data"`
}
type GenesisResponse_GenesisJson struct {
GenesisTime string `json:"genesis_time" time:"true"`
GenesisValidatorsRoot string `json:"genesis_validators_root" hex:"true"`
GenesisForkVersion string `json:"genesis_fork_version" hex:"true"`
}
// WeakSubjectivityResponse is used to marshal/unmarshal the response for the
// /eth/v1/beacon/weak_subjectivity endpoint.
type WeakSubjectivityResponse struct {
@@ -41,42 +31,6 @@ type StateRootResponse_StateRootJson struct {
StateRoot string `json:"root" hex:"true"`
}
type StateFinalityCheckpointResponseJson struct {
Data *StateFinalityCheckpointResponse_StateFinalityCheckpointJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type StateFinalityCheckpointResponse_StateFinalityCheckpointJson struct {
PreviousJustified *CheckpointJson `json:"previous_justified"`
CurrentJustified *CheckpointJson `json:"current_justified"`
Finalized *CheckpointJson `json:"finalized"`
}
type StateValidatorsResponseJson struct {
Data []*ValidatorContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type StateValidatorResponseJson struct {
Data *ValidatorContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type ValidatorBalancesResponseJson struct {
Data []*ValidatorBalanceJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type StateCommitteesResponseJson struct {
Data []*CommitteeJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type SyncCommitteesResponseJson struct {
Data *SyncCommitteeValidatorsJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
@@ -91,18 +45,6 @@ type RandaoResponseJson struct {
Finalized bool `json:"finalized"`
}
type BlockHeadersResponseJson struct {
Data []*BlockHeaderContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type BlockHeaderResponseJson struct {
Data *BlockHeaderContainerJson `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type BlockResponseJson struct {
Data *SignedBeaconBlockJson `json:"data"`
}
@@ -207,10 +149,6 @@ type SpecResponseJson struct {
Data interface{} `json:"data"`
}
type ValidatorIndicesJson struct {
Index []string `json:"index"`
}
type ProduceBlockResponseJson struct {
Data *BeaconBlockJson `json:"data"`
}
@@ -277,13 +215,6 @@ type ForkChoiceResponseExtraDataJson struct {
HeadRoot string `json:"head_root" hex:"true"`
}
type LivenessResponseJson struct {
Data []*struct {
Index string `json:"index"`
IsLive bool `json:"is_live"`
} `json:"data"`
}
//----------------
// Reusable types.
//----------------
@@ -717,17 +648,6 @@ type SyncAggregateJson struct {
SyncCommitteeSignature string `json:"sync_committee_signature" hex:"true"`
}
type BlockHeaderContainerJson struct {
Root string `json:"root" hex:"true"`
Canonical bool `json:"canonical"`
Header *BeaconBlockHeaderContainerJson `json:"header"`
}
type BeaconBlockHeaderContainerJson struct {
Message *BeaconBlockHeaderJson `json:"message"`
Signature string `json:"signature" hex:"true"`
}
type SignedBeaconBlockHeaderJson struct {
Header *BeaconBlockHeaderJson `json:"message"`
Signature string `json:"signature" hex:"true"`
@@ -1001,13 +921,6 @@ type ForkJson struct {
Epoch string `json:"epoch"`
}
type ValidatorContainerJson struct {
Index string `json:"index"`
Balance string `json:"balance"`
Status string `json:"status" enum:"true"`
Validator *ValidatorJson `json:"validator"`
}
type ValidatorJson struct {
PublicKey string `json:"pubkey" hex:"true"`
WithdrawalCredentials string `json:"withdrawal_credentials" hex:"true"`
@@ -1019,17 +932,6 @@ type ValidatorJson struct {
WithdrawableEpoch string `json:"withdrawable_epoch"`
}
type ValidatorBalanceJson struct {
Index string `json:"index"`
Balance string `json:"balance"`
}
type CommitteeJson struct {
Index string `json:"index"`
Slot string `json:"slot"`
Validators []string `json:"validators"`
}
type SyncCommitteeJson struct {
Pubkeys []string `json:"pubkeys" hex:"true"`
AggregatePubkey string `json:"aggregate_pubkey" hex:"true"`
@@ -1290,11 +1192,6 @@ type SingleIndexedVerificationFailureJson struct {
Message string `json:"message"`
}
type NodeSyncDetailsErrorJson struct {
apimiddleware.DefaultErrorJson
SyncDetails shared.SyncDetails `json:"sync_details"`
}
type EventErrorJson struct {
StatusCode int `json:"status_code"`
Message string `json:"message"`

View File

@@ -8,13 +8,13 @@ go_library(
"config.go",
"handlers.go",
"handlers_pool.go",
"handlers_validator.go",
"log.go",
"pool.go",
"server.go",
"state.go",
"structs.go",
"sync_committee.go",
"validator.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon",
visibility = ["//visibility:public"],
@@ -77,7 +77,6 @@ go_library(
"@org_golang_google_grpc//metadata:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
],
)
@@ -89,12 +88,12 @@ go_test(
"config_test.go",
"handlers_pool_test.go",
"handlers_test.go",
"handlers_validators_test.go",
"init_test.go",
"pool_test.go",
"server_test.go",
"state_test.go",
"sync_committee_test.go",
"validator_test.go",
],
embed = [":go_default_library"],
deps = [
@@ -115,7 +114,6 @@ go_test(
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/core:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
@@ -128,7 +126,6 @@ go_test(
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/bls/common:go_default_library",
"//crypto/hash:go_default_library",

View File

@@ -261,8 +261,8 @@ func (bs *Server) SubmitBlindedBlockSSZ(ctx context.Context, req *ethpbv2.SSZCon
_, err = bs.V1Alpha1ValidatorServer.ProposeBeaconBlock(ctx, &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedDeneb{
BlindedDeneb: &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: b,
Blobs: migration.SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs(blkContent.SignedBlindedBlobSidecars),
SignedBlindedBlock: b,
SignedBlindedBlobSidecars: migration.SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs(blkContent.SignedBlindedBlobSidecars),
},
},
})
@@ -563,7 +563,7 @@ func (bs *Server) getBlindedBlockDeneb(ctx context.Context, blk interfaces.ReadO
if blindedDenebBlk == nil {
return nil, errNilBlock
}
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlk.Block)
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlk.Message)
if err != nil {
return nil, errors.Wrapf(err, "Could not convert beacon block")
}
@@ -601,7 +601,7 @@ func (bs *Server) getBlindedBlockDeneb(ctx context.Context, blk interfaces.ReadO
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlock.Block)
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlock.Message)
if err != nil {
return nil, errors.Wrapf(err, "could not convert beacon block")
}
@@ -783,7 +783,7 @@ func (bs *Server) getBlindedSSZBlockDeneb(ctx context.Context, blk interfaces.Re
if blindedDenebBlk == nil {
return nil, errNilBlock
}
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlk.Block)
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlk.Message)
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
@@ -825,7 +825,7 @@ func (bs *Server) getBlindedSSZBlockDeneb(ctx context.Context, blk interfaces.Re
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlock.Block)
v2Blk, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(blindedDenebBlock.Message)
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
@@ -905,8 +905,8 @@ func (bs *Server) submitBlindedDenebContents(ctx context.Context, blindedDenebCo
_, err = bs.V1Alpha1ValidatorServer.ProposeBeaconBlock(ctx, &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedDeneb{
BlindedDeneb: &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: blk,
Blobs: blobs,
SignedBlindedBlock: blk,
SignedBlindedBlobSidecars: blobs,
},
},
})

View File

@@ -120,7 +120,7 @@ func TestServer_GetBlindedBlock(t *testing.T) {
OptimisticModeFetcher: mockChainService,
}
expected, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(b.Block)
expected, err := migration.V1Alpha1BeaconBlockBlindedDenebToV2Blinded(b.Message)
require.NoError(t, err)
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)

View File

@@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
@@ -80,122 +79,6 @@ func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*eth
}, nil
}
// GetBlockHeader retrieves block header for given block id.
func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest) (*ethpbv1.BlockHeaderResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockHeader")
defer span.End()
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
}
v1alpha1Header, err := blk.Header()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get block header from block: %v", err)
}
header := migration.V1Alpha1SignedHeaderToV1(v1alpha1Header)
headerRoot, err := header.Message.HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not hash block header: %v", err)
}
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not hash block: %v", err)
}
canonical, err := bs.ChainInfoFetcher.IsCanonical(ctx, blkRoot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine if block root is canonical: %v", err)
}
isOptimistic, err := bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if block is optimistic: %v", err)
}
return &ethpbv1.BlockHeaderResponse{
Data: &ethpbv1.BlockHeaderContainer{
Root: headerRoot[:],
Canonical: canonical,
Header: &ethpbv1.BeaconBlockHeaderContainer{
Message: header.Message,
Signature: header.Signature,
},
},
ExecutionOptimistic: isOptimistic,
Finalized: bs.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}, nil
}
// ListBlockHeaders retrieves block headers matching given query. By default it will fetch current head slot blocks.
func (bs *Server) ListBlockHeaders(ctx context.Context, req *ethpbv1.BlockHeadersRequest) (*ethpbv1.BlockHeadersResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.ListBlockHeaders")
defer span.End()
var err error
var blks []interfaces.ReadOnlySignedBeaconBlock
var blkRoots [][32]byte
if len(req.ParentRoot) == 32 {
blks, blkRoots, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetParentRoot(req.ParentRoot))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve blocks: %v", err)
}
} else {
slot := bs.ChainInfoFetcher.HeadSlot()
if req.Slot != nil {
slot = *req.Slot
}
blks, err = bs.BeaconDB.BlocksBySlot(ctx, slot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve blocks for slot %d: %v", req.Slot, err)
}
_, blkRoots, err = bs.BeaconDB.BlockRootsBySlot(ctx, slot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve block roots for slot %d: %v", req.Slot, err)
}
}
if len(blks) == 0 {
return nil, status.Error(codes.NotFound, "Could not find requested blocks")
}
isOptimistic := false
isFinalized := true
blkHdrs := make([]*ethpbv1.BlockHeaderContainer, len(blks))
for i, bl := range blks {
v1alpha1Header, err := bl.Header()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get block header from block: %v", err)
}
header := migration.V1Alpha1SignedHeaderToV1(v1alpha1Header)
headerRoot, err := header.Message.HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not hash block header: %v", err)
}
canonical, err := bs.ChainInfoFetcher.IsCanonical(ctx, blkRoots[i])
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine if block root is canonical: %v", err)
}
if !isOptimistic {
isOptimistic, err = bs.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoots[i])
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if block is optimistic: %v", err)
}
}
if isFinalized {
isFinalized = bs.FinalizationFetcher.IsFinalized(ctx, blkRoots[i])
}
blkHdrs[i] = &ethpbv1.BlockHeaderContainer{
Root: headerRoot[:],
Canonical: canonical,
Header: &ethpbv1.BeaconBlockHeaderContainer{
Message: header.Message,
Signature: header.Signature,
},
}
}
return &ethpbv1.BlockHeadersResponse{Data: blkHdrs, ExecutionOptimistic: isOptimistic, Finalized: isFinalized}, nil
}
// SubmitBlock instructs the beacon node to broadcast a newly signed beacon block to the beacon network, to be
// included in the beacon chain. The beacon node is not required to validate the signed ReadOnlyBeaconBlock, and a successful
// response (20X) only indicates that the broadcast has been successful. The beacon node is expected to integrate the

View File

@@ -10,7 +10,6 @@ import (
"github.com/prysmaticlabs/prysm/v4/api"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
@@ -67,292 +66,6 @@ func fillDBTestBlocks(ctx context.Context, t *testing.T, beaconDB db.Database) (
return genBlk, blkContainers
}
func TestServer_GetBlockHeader(t *testing.T) {
ctx := context.Background()
b := util.NewBeaconBlock()
b.Block.Slot = 123
b.Block.ProposerIndex = 123
b.Block.StateRoot = bytesutil.PadTo([]byte("stateroot"), 32)
sb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockBlockFetcher := &testutil.MockBlocker{BlockToReturn: sb}
t.Run("get header", func(t *testing.T) {
mockChainService := &mock.ChainService{
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
header, err := bs.GetBlockHeader(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
expectedBodyRoot, err := sb.Block().Body().HashTreeRoot()
require.NoError(t, err)
expectedParentRoot := sb.Block().ParentRoot()
expectedHeader := &ethpbv1.BeaconBlockHeader{
Slot: sb.Block().Slot(),
ProposerIndex: sb.Block().ProposerIndex(),
ParentRoot: expectedParentRoot[:],
StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
BodyRoot: expectedBodyRoot[:],
}
expectedHeaderRoot, err := expectedHeader.HashTreeRoot()
require.NoError(t, err)
headerRoot, err := header.Data.Header.Message.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHeaderRoot, headerRoot)
assert.Equal(t, sb.Block().Slot(), header.Data.Header.Message.Slot)
expectedStateRoot := sb.Block().StateRoot()
assert.DeepEqual(t, expectedStateRoot[:], header.Data.Header.Message.StateRoot)
assert.DeepEqual(t, expectedParentRoot[:], header.Data.Header.Message.ParentRoot)
assert.DeepEqual(t, expectedBodyRoot[:], header.Data.Header.Message.BodyRoot)
assert.Equal(t, sb.Block().ProposerIndex(), header.Data.Header.Message.ProposerIndex)
})
t.Run("execution optimistic", func(t *testing.T) {
r, err := sb.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
OptimisticRoots: map[[32]byte]bool{r: true},
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
header, err := bs.GetBlockHeader(ctx, &ethpbv1.BlockRequest{BlockId: []byte("head")})
require.NoError(t, err)
assert.Equal(t, true, header.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
r, err := sb.Block().HashTreeRoot()
require.NoError(t, err)
t.Run("true", func(t *testing.T) {
mockChainService := &mock.ChainService{FinalizedRoots: map[[32]byte]bool{r: true}}
bs := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
header, err := bs.GetBlockHeader(ctx, &ethpbv1.BlockRequest{BlockId: r[:]})
require.NoError(t, err)
assert.Equal(t, true, header.Finalized)
})
t.Run("false", func(t *testing.T) {
mockChainService := &mock.ChainService{FinalizedRoots: map[[32]byte]bool{r: false}}
bs := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
header, err := bs.GetBlockHeader(ctx, &ethpbv1.BlockRequest{BlockId: r[:]})
require.NoError(t, err)
assert.Equal(t, false, header.Finalized)
})
})
}
func TestServer_ListBlockHeaders(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
b1 := util.NewBeaconBlock()
b1.Block.Slot = 30
b1.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b1)
b2 := util.NewBeaconBlock()
b2.Block.Slot = 30
b2.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
util.SaveBlock(t, ctx, beaconDB, b2)
b3 := util.NewBeaconBlock()
b3.Block.Slot = 31
b3.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b3)
b4 := util.NewBeaconBlock()
b4.Block.Slot = 28
b4.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b4)
t.Run("list headers", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
mockChainFetcher := &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
tests := []struct {
name string
slot primitives.Slot
parentRoot []byte
want []*ethpbalpha.SignedBeaconBlock
wantErr bool
}{
{
name: "slot",
slot: primitives.Slot(30),
want: []*ethpbalpha.SignedBeaconBlock{
blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
b1,
b2,
},
},
{
name: "parent root",
parentRoot: b1.Block.ParentRoot,
want: []*ethpbalpha.SignedBeaconBlock{
blkContainers[1].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
b1,
b3,
b4,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
headers, err := bs.ListBlockHeaders(ctx, &ethpbv1.BlockHeadersRequest{
Slot: &tt.slot,
ParentRoot: tt.parentRoot,
})
require.NoError(t, err)
require.Equal(t, len(tt.want), len(headers.Data))
for i, blk := range tt.want {
expectedBodyRoot, err := blk.Block.Body.HashTreeRoot()
require.NoError(t, err)
expectedHeader := &ethpbv1.BeaconBlockHeader{
Slot: blk.Block.Slot,
ProposerIndex: blk.Block.ProposerIndex,
ParentRoot: blk.Block.ParentRoot,
StateRoot: make([]byte, 32),
BodyRoot: expectedBodyRoot[:],
}
expectedHeaderRoot, err := expectedHeader.HashTreeRoot()
require.NoError(t, err)
headerRoot, err := headers.Data[i].Header.Message.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHeaderRoot, headerRoot)
assert.Equal(t, blk.Block.Slot, headers.Data[i].Header.Message.Slot)
assert.DeepEqual(t, blk.Block.StateRoot, headers.Data[i].Header.Message.StateRoot)
assert.DeepEqual(t, blk.Block.ParentRoot, headers.Data[i].Header.Message.ParentRoot)
expectedRoot, err := blk.Block.Body.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedRoot[:], headers.Data[i].Header.Message.BodyRoot)
assert.Equal(t, blk.Block.ProposerIndex, headers.Data[i].Header.Message.ProposerIndex)
}
})
}
})
t.Run("execution optimistic", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
mockChainFetcher := &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
Optimistic: true,
FinalizedRoots: map[[32]byte]bool{},
OptimisticRoots: map[[32]byte]bool{
bytesutil.ToBytes32(blkContainers[30].BlockRoot): true,
},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
slot := primitives.Slot(30)
headers, err := bs.ListBlockHeaders(ctx, &ethpbv1.BlockHeadersRequest{
Slot: &slot,
})
require.NoError(t, err)
assert.Equal(t, true, headers.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
child1 := util.NewBeaconBlock()
child1.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
child1.Block.Slot = 999
util.SaveBlock(t, ctx, beaconDB, child1)
child2 := util.NewBeaconBlock()
child2.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
child2.Block.Slot = 1000
util.SaveBlock(t, ctx, beaconDB, child2)
child1Root, err := child1.Block.HashTreeRoot()
require.NoError(t, err)
child2Root, err := child2.Block.HashTreeRoot()
require.NoError(t, err)
mockChainFetcher := &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{child1Root: true, child2Root: false},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
t.Run("true", func(t *testing.T) {
slot := primitives.Slot(999)
headers, err := bs.ListBlockHeaders(ctx, &ethpbv1.BlockHeadersRequest{
Slot: &slot,
})
require.NoError(t, err)
assert.Equal(t, true, headers.Finalized)
})
t.Run("false", func(t *testing.T) {
slot := primitives.Slot(1000)
headers, err := bs.ListBlockHeaders(ctx, &ethpbv1.BlockHeadersRequest{
Slot: &slot,
})
require.NoError(t, err)
assert.Equal(t, false, headers.Finalized)
})
t.Run("false when at least one not finalized", func(t *testing.T) {
headers, err := bs.ListBlockHeaders(ctx, &ethpbv1.BlockHeadersRequest{
ParentRoot: []byte("parent"),
})
require.NoError(t, err)
assert.Equal(t, false, headers.Finalized)
})
})
}
func TestServer_SubmitBlock(t *testing.T) {
ctrl := gomock.NewController(t)

View File

@@ -16,6 +16,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/api"
corehelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
@@ -671,7 +672,7 @@ func (s *Server) GetCommittees(w http.ResponseWriter, r *http.Request) {
st, err := s.Stater.State(ctx, []byte(stateId))
if err != nil {
helpers.HandleStateFetchError(w, err)
shared.WriteStateFetchError(w, err)
return
}
@@ -739,7 +740,7 @@ func (s *Server) GetCommittees(w http.ResponseWriter, r *http.Request) {
}
// GetDepositContract retrieves deposit contract address and genesis fork version.
func (_ *Server) GetDepositContract(w http.ResponseWriter, r *http.Request) {
func (*Server) GetDepositContract(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "beacon.GetDepositContract")
defer span.End()
@@ -753,3 +754,230 @@ func (_ *Server) GetDepositContract(w http.ResponseWriter, r *http.Request) {
},
})
}
// GetBlockHeaders retrieves block headers matching given query. By default it will fetch current head slot blocks.
func (s *Server) GetBlockHeaders(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlockHeaders")
defer span.End()
rawSlot := r.URL.Query().Get("slot")
rawParentRoot := r.URL.Query().Get("parent_root")
var err error
var blks []interfaces.ReadOnlySignedBeaconBlock
var blkRoots [][32]byte
if rawParentRoot != "" {
parentRoot, valid := shared.ValidateHex(w, "Parent Root", rawParentRoot, 32)
if !valid {
return
}
blks, blkRoots, err = s.BeaconDB.Blocks(ctx, filters.NewFilter().SetParentRoot(parentRoot))
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not retrieve blocks for parent root %s", parentRoot).Error(), http.StatusInternalServerError)
return
}
} else {
slot := uint64(s.ChainInfoFetcher.HeadSlot())
if rawSlot != "" {
var valid bool
slot, valid = shared.ValidateUint(w, "Slot", rawSlot)
if !valid {
return
}
}
blks, err = s.BeaconDB.BlocksBySlot(ctx, primitives.Slot(slot))
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not retrieve blocks for slot %d", slot).Error(), http.StatusInternalServerError)
return
}
_, blkRoots, err = s.BeaconDB.BlockRootsBySlot(ctx, primitives.Slot(slot))
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not retrieve blocks for slot %d", slot).Error(), http.StatusInternalServerError)
return
}
}
isOptimistic := false
isFinalized := true
blkHdrs := make([]*shared.SignedBeaconBlockHeaderContainer, len(blks))
for i, bl := range blks {
v1alpha1Header, err := bl.Header()
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not get block header from block").Error(), http.StatusInternalServerError)
return
}
headerRoot, err := v1alpha1Header.Header.HashTreeRoot()
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not hash block header").Error(), http.StatusInternalServerError)
return
}
canonical, err := s.ChainInfoFetcher.IsCanonical(ctx, blkRoots[i])
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not determine if block root is canonical").Error(), http.StatusInternalServerError)
return
}
if !isOptimistic {
isOptimistic, err = s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoots[i])
if err != nil {
http2.HandleError(w, errors.Wrapf(err, "Could not check if block is optimistic").Error(), http.StatusInternalServerError)
return
}
}
if isFinalized {
isFinalized = s.FinalizationFetcher.IsFinalized(ctx, blkRoots[i])
}
blkHdrs[i] = &shared.SignedBeaconBlockHeaderContainer{
Header: &shared.SignedBeaconBlockHeader{
Message: shared.BeaconBlockHeaderFromConsensus(v1alpha1Header.Header),
Signature: hexutil.Encode(v1alpha1Header.Signature),
},
Root: hexutil.Encode(headerRoot[:]),
Canonical: canonical,
}
}
response := &GetBlockHeadersResponse{
Data: blkHdrs,
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, response)
}
// GetBlockHeader retrieves block header for given block id.
func (s *Server) GetBlockHeader(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlockHeader")
defer span.End()
blockID := mux.Vars(r)["block_id"]
if blockID == "" {
http2.HandleError(w, "block_id is required in URL params", http.StatusBadRequest)
return
}
blk, err := s.Blocker.Block(ctx, []byte(blockID))
ok := shared.WriteBlockFetchError(w, blk, err)
if !ok {
return
}
blockHeader, err := blk.Header()
if err != nil {
http2.HandleError(w, "Could not get block header: %s"+err.Error(), http.StatusInternalServerError)
return
}
headerRoot, err := blockHeader.Header.HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not hash block header: %s"+err.Error(), http.StatusInternalServerError)
return
}
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not hash block: %s"+err.Error(), http.StatusInternalServerError)
return
}
canonical, err := s.ChainInfoFetcher.IsCanonical(ctx, blkRoot)
if err != nil {
http2.HandleError(w, "Could not determine if block root is canonical: %s"+err.Error(), http.StatusInternalServerError)
return
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoot)
if err != nil {
http2.HandleError(w, "Could not check if block is optimistic: %s"+err.Error(), http.StatusInternalServerError)
return
}
resp := &GetBlockHeaderResponse{
Data: &shared.SignedBeaconBlockHeaderContainer{
Root: hexutil.Encode(headerRoot[:]),
Canonical: canonical,
Header: &shared.SignedBeaconBlockHeader{
Message: shared.BeaconBlockHeaderFromConsensus(blockHeader.Header),
Signature: hexutil.Encode(blockHeader.Signature),
},
},
ExecutionOptimistic: isOptimistic,
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}
http2.WriteJson(w, resp)
}
// GetFinalityCheckpoints returns finality checkpoints for state with given 'stateId'. In case finality is
// not yet achieved, checkpoint should return epoch 0 and ZERO_HASH as root.
func (s *Server) GetFinalityCheckpoints(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetFinalityCheckpoints")
defer span.End()
stateId := mux.Vars(r)["state_id"]
if stateId == "" {
http2.HandleError(w, "state_id is required in URL params", http.StatusBadRequest)
return
}
st, err := s.Stater.State(ctx, []byte(stateId))
if err != nil {
shared.WriteStateFetchError(w, err)
return
}
isOptimistic, err := helpers.IsOptimistic(ctx, []byte(stateId), s.OptimisticModeFetcher, s.Stater, s.ChainInfoFetcher, s.BeaconDB)
if err != nil {
http2.HandleError(w, "Could not check if slot's block is optimistic: "+err.Error(), http.StatusInternalServerError)
return
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not calculate root of latest block header: "+err.Error(), http.StatusInternalServerError)
return
}
isFinalized := s.FinalizationFetcher.IsFinalized(ctx, blockRoot)
pj := st.PreviousJustifiedCheckpoint()
cj := st.CurrentJustifiedCheckpoint()
f := st.FinalizedCheckpoint()
resp := &GetFinalityCheckpointsResponse{
Data: &FinalityCheckpoints{
PreviousJustified: &shared.Checkpoint{
Epoch: strconv.FormatUint(uint64(pj.Epoch), 10),
Root: hexutil.Encode(pj.Root),
},
CurrentJustified: &shared.Checkpoint{
Epoch: strconv.FormatUint(uint64(cj.Epoch), 10),
Root: hexutil.Encode(cj.Root),
},
Finalized: &shared.Checkpoint{
Epoch: strconv.FormatUint(uint64(f.Epoch), 10),
Root: hexutil.Encode(f.Root),
},
},
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
}
// GetGenesis retrieves details of the chain's genesis which can be used to identify chain.
func (s *Server) GetGenesis(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "beacon.GetGenesis")
defer span.End()
genesisTime := s.GenesisTimeFetcher.GenesisTime()
if genesisTime.IsZero() {
http2.HandleError(w, "Chain genesis info is not yet known", http.StatusNotFound)
return
}
validatorsRoot := s.ChainInfoFetcher.GenesisValidatorsRoot()
if bytes.Equal(validatorsRoot[:], params.BeaconConfig().ZeroHash[:]) {
http2.HandleError(w, "Chain genesis info is not yet known", http.StatusNotFound)
return
}
forkVersion := params.BeaconConfig().GenesisForkVersion
resp := &GetGenesisResponse{
Data: &Genesis{
GenesisTime: strconv.FormatUint(uint64(genesisTime.Unix()), 10),
GenesisValidatorsRoot: hexutil.Encode(validatorsRoot[:]),
GenesisForkVersion: hexutil.Encode(forkVersion),
},
}
http2.WriteJson(w, resp)
}

View File

@@ -10,6 +10,7 @@ import (
"strconv"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
@@ -30,6 +31,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
@@ -395,7 +397,7 @@ func TestPublishBlindedBlockV2(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool {
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedDeneb)
converted, err := shared.BlindedBeaconBlockDenebFromConsensus(block.BlindedDeneb.Block.Block)
converted, err := shared.BlindedBeaconBlockDenebFromConsensus(block.BlindedDeneb.SignedBlindedBlock.Message)
require.NoError(t, err)
var signedblock *shared.SignedBlindedBeaconBlockContentsDeneb
err = json.Unmarshal([]byte(rpctesting.BlindedDenebBlockContents), &signedblock)
@@ -1134,3 +1136,521 @@ func TestGetCommittees(t *testing.T) {
assert.Equal(t, true, resp.Finalized)
})
}
func TestGetBlockHeaders(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
b1 := util.NewBeaconBlock()
b1.Block.Slot = 30
b1.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b1)
b2 := util.NewBeaconBlock()
b2.Block.Slot = 30
b2.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
util.SaveBlock(t, ctx, beaconDB, b2)
b3 := util.NewBeaconBlock()
b3.Block.Slot = 31
b3.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b3)
b4 := util.NewBeaconBlock()
b4.Block.Slot = 28
b4.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b4)
url := "http://example.com/eth/v1/beacon/headers"
t.Run("list headers", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*eth.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
mockChainFetcher := &chainMock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &eth.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
tests := []struct {
name string
slot primitives.Slot
parentRoot string
want []*eth.SignedBeaconBlock
wantErr bool
}{
{
name: "slot",
slot: primitives.Slot(30),
parentRoot: "",
want: []*eth.SignedBeaconBlock{
blkContainers[30].Block.(*eth.BeaconBlockContainer_Phase0Block).Phase0Block,
b1,
b2,
},
},
{
name: "parent root",
parentRoot: hexutil.Encode(b1.Block.ParentRoot),
want: []*eth.SignedBeaconBlock{
blkContainers[1].Block.(*eth.BeaconBlockContainer_Phase0Block).Phase0Block,
b1,
b3,
b4,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
urlWithParams := fmt.Sprintf("%s?slot=%d&parent_root=%s", url, tt.slot, tt.parentRoot)
request := httptest.NewRequest(http.MethodGet, urlWithParams, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
bs.GetBlockHeaders(writer, request)
resp := &GetBlockHeadersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, len(tt.want), len(resp.Data))
for i, blk := range tt.want {
expectedBodyRoot, err := blk.Block.Body.HashTreeRoot()
require.NoError(t, err)
expectedHeader := &eth.BeaconBlockHeader{
Slot: blk.Block.Slot,
ProposerIndex: blk.Block.ProposerIndex,
ParentRoot: blk.Block.ParentRoot,
StateRoot: make([]byte, 32),
BodyRoot: expectedBodyRoot[:],
}
expectedHeaderRoot, err := expectedHeader.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, hexutil.Encode(expectedHeaderRoot[:]), resp.Data[i].Root)
assert.DeepEqual(t, shared.BeaconBlockHeaderFromConsensus(expectedHeader), resp.Data[i].Header.Message)
}
})
}
})
t.Run("execution optimistic", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*eth.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
mockChainFetcher := &chainMock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &eth.Checkpoint{Root: blkContainers[64].BlockRoot},
Optimistic: true,
FinalizedRoots: map[[32]byte]bool{},
OptimisticRoots: map[[32]byte]bool{
bytesutil.ToBytes32(blkContainers[30].BlockRoot): true,
},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
slot := primitives.Slot(30)
urlWithParams := fmt.Sprintf("%s?slot=%d", url, slot)
request := httptest.NewRequest(http.MethodGet, urlWithParams, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
bs.GetBlockHeaders(writer, request)
resp := &GetBlockHeadersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*eth.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
child1 := util.NewBeaconBlock()
child1.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
child1.Block.Slot = 999
util.SaveBlock(t, ctx, beaconDB, child1)
child2 := util.NewBeaconBlock()
child2.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
child2.Block.Slot = 1000
util.SaveBlock(t, ctx, beaconDB, child2)
child1Root, err := child1.Block.HashTreeRoot()
require.NoError(t, err)
child2Root, err := child2.Block.HashTreeRoot()
require.NoError(t, err)
mockChainFetcher := &chainMock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &eth.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{child1Root: true, child2Root: false},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainFetcher,
OptimisticModeFetcher: mockChainFetcher,
FinalizationFetcher: mockChainFetcher,
}
t.Run("true", func(t *testing.T) {
slot := primitives.Slot(999)
urlWithParams := fmt.Sprintf("%s?slot=%d", url, slot)
request := httptest.NewRequest(http.MethodGet, urlWithParams, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
bs.GetBlockHeaders(writer, request)
resp := &GetBlockHeadersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
t.Run("false", func(t *testing.T) {
slot := primitives.Slot(1000)
urlWithParams := fmt.Sprintf("%s?slot=%d", url, slot)
request := httptest.NewRequest(http.MethodGet, urlWithParams, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
bs.GetBlockHeaders(writer, request)
resp := &GetBlockHeadersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, false, resp.Finalized)
})
t.Run("false when at least one not finalized", func(t *testing.T) {
urlWithParams := fmt.Sprintf("%s?parent_root=%s", url, hexutil.Encode(child1.Block.ParentRoot))
request := httptest.NewRequest(http.MethodGet, urlWithParams, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
bs.GetBlockHeaders(writer, request)
resp := &GetBlockHeadersResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, false, resp.Finalized)
})
})
}
func TestServer_GetBlockHeader(t *testing.T) {
b := util.NewBeaconBlock()
b.Block.Slot = 123
b.Block.ProposerIndex = 123
b.Block.StateRoot = bytesutil.PadTo([]byte("stateroot"), 32)
b.Block.ParentRoot = bytesutil.PadTo([]byte("parentroot"), 32)
b.Block.Body.Graffiti = bytesutil.PadTo([]byte("graffiti"), 32)
sb, err := blocks.NewSignedBeaconBlock(b)
sb.SetSignature(bytesutil.PadTo([]byte("sig"), 96))
require.NoError(t, err)
mockBlockFetcher := &testutil.MockBlocker{BlockToReturn: sb}
mockChainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{},
}
s := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
t.Run("ok", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/headers/{block_id}", nil)
request = mux.SetURLVars(request, map[string]string{"block_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockHeader(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetBlockHeaderResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Data.Canonical)
assert.Equal(t, "0xd7d92f6206707f2c9c4e7e82320617d5abac2b6461a65ea5bb1a154b5b5ea2fa", resp.Data.Root)
assert.Equal(t, "0x736967000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", resp.Data.Header.Signature)
assert.Equal(t, "123", resp.Data.Header.Message.Slot)
assert.Equal(t, "0x706172656e74726f6f7400000000000000000000000000000000000000000000", resp.Data.Header.Message.ParentRoot)
assert.Equal(t, "123", resp.Data.Header.Message.ProposerIndex)
assert.Equal(t, "0xdd32cbaa01c6c0ef399b293f86884ce6a15b532d34682edb16a48fa70ea5bc79", resp.Data.Header.Message.BodyRoot)
assert.Equal(t, "0x7374617465726f6f740000000000000000000000000000000000000000000000", resp.Data.Header.Message.StateRoot)
})
t.Run("missing block_id", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/headers/{block_id}", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockHeader(writer, request)
require.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "block_id is required in URL params", e.Message)
})
t.Run("execution optimistic", func(t *testing.T) {
r, err := sb.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &chainMock.ChainService{
OptimisticRoots: map[[32]byte]bool{r: true},
FinalizedRoots: map[[32]byte]bool{},
}
s := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/headers/{block_id}", nil)
request = mux.SetURLVars(request, map[string]string{"block_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockHeader(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetBlockHeaderResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
r, err := sb.Block().HashTreeRoot()
require.NoError(t, err)
t.Run("true", func(t *testing.T) {
mockChainService := &chainMock.ChainService{FinalizedRoots: map[[32]byte]bool{r: true}}
s := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/headers/{block_id}", nil)
request = mux.SetURLVars(request, map[string]string{"block_id": hexutil.Encode(r[:])})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockHeader(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetBlockHeaderResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
t.Run("false", func(t *testing.T) {
mockChainService := &chainMock.ChainService{FinalizedRoots: map[[32]byte]bool{r: false}}
s := &Server{
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/headers/{block_id}", nil)
request = mux.SetURLVars(request, map[string]string{"block_id": hexutil.Encode(r[:])})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockHeader(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &GetBlockHeaderResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, false, resp.Finalized)
})
})
}
func TestGetFinalityCheckpoints(t *testing.T) {
fillCheckpoints := func(state *eth.BeaconState) error {
state.PreviousJustifiedCheckpoint = &eth.Checkpoint{
Root: bytesutil.PadTo([]byte("previous"), 32),
Epoch: 113,
}
state.CurrentJustifiedCheckpoint = &eth.Checkpoint{
Root: bytesutil.PadTo([]byte("current"), 32),
Epoch: 123,
}
state.FinalizedCheckpoint = &eth.Checkpoint{
Root: bytesutil.PadTo([]byte("finalized"), 32),
Epoch: 103,
}
return nil
}
fakeState, err := util.NewBeaconState(fillCheckpoints)
require.NoError(t, err)
chainService := &chainMock.ChainService{}
s := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
t.Run("ok", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/states/{state_id}/finality_checkpoints", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetFinalityCheckpoints(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetFinalityCheckpointsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.NotNil(t, resp.Data)
assert.Equal(t, strconv.FormatUint(uint64(fakeState.FinalizedCheckpoint().Epoch), 10), resp.Data.Finalized.Epoch)
assert.DeepEqual(t, hexutil.Encode(fakeState.FinalizedCheckpoint().Root), resp.Data.Finalized.Root)
assert.Equal(t, strconv.FormatUint(uint64(fakeState.CurrentJustifiedCheckpoint().Epoch), 10), resp.Data.CurrentJustified.Epoch)
assert.DeepEqual(t, hexutil.Encode(fakeState.CurrentJustifiedCheckpoint().Root), resp.Data.CurrentJustified.Root)
assert.Equal(t, strconv.FormatUint(uint64(fakeState.PreviousJustifiedCheckpoint().Epoch), 10), resp.Data.PreviousJustified.Epoch)
assert.DeepEqual(t, hexutil.Encode(fakeState.PreviousJustifiedCheckpoint().Root), resp.Data.PreviousJustified.Root)
})
t.Run("no state_id", func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/states/{state_id}/finality_checkpoints", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetFinalityCheckpoints(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "state_id is required in URL params", e.Message)
})
t.Run("execution optimistic", func(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/states/{state_id}/finality_checkpoints", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetFinalityCheckpoints(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetFinalityCheckpointsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
headerRoot, err := fakeState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/states/{state_id}/finality_checkpoints", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetFinalityCheckpoints(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetFinalityCheckpointsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
}
func TestGetGenesis(t *testing.T) {
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig().Copy()
config.GenesisForkVersion = []byte("genesis")
params.OverrideBeaconConfig(config)
genesis := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)
validatorsRoot := [32]byte{1, 2, 3, 4, 5, 6}
t.Run("ok", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: genesis,
ValidatorsRoot: validatorsRoot,
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/genesis", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetGenesis(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetGenesisResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.NotNil(t, resp.Data)
assert.Equal(t, strconv.FormatInt(genesis.Unix(), 10), resp.Data.GenesisTime)
assert.DeepEqual(t, hexutil.Encode(validatorsRoot[:]), resp.Data.GenesisValidatorsRoot)
assert.DeepEqual(t, hexutil.Encode([]byte("genesis")), resp.Data.GenesisForkVersion)
})
t.Run("no genesis time", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: time.Time{},
ValidatorsRoot: validatorsRoot,
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/genesis", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetGenesis(writer, request)
assert.Equal(t, http.StatusNotFound, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusNotFound, e.Code)
assert.StringContains(t, "Chain genesis info is not yet known", e.Message)
})
t.Run("no genesis validators root", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: genesis,
ValidatorsRoot: [32]byte{},
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "/eth/v1/beacon/genesis", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetGenesis(writer, request)
assert.Equal(t, http.StatusNotFound, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusNotFound, e.Code)
assert.StringContains(t, "Chain genesis info is not yet known", e.Message)
})
}

View File

@@ -0,0 +1,379 @@
package beacon
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/mux"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
statenative "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"go.opencensus.io/trace"
)
// GetValidators returns filterable list of validators with their balance, status and index.
func (s *Server) GetValidators(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetValidators")
defer span.End()
stateId := mux.Vars(r)["state_id"]
if stateId == "" {
http2.HandleError(w, "state_id is required in URL params", http.StatusBadRequest)
return
}
st, err := s.Stater.State(ctx, []byte(stateId))
if err != nil {
shared.WriteStateFetchError(w, err)
return
}
isOptimistic, err := helpers.IsOptimistic(ctx, []byte(stateId), s.OptimisticModeFetcher, s.Stater, s.ChainInfoFetcher, s.BeaconDB)
if err != nil {
http2.HandleError(w, "Could not check optimistic status: "+err.Error(), http.StatusInternalServerError)
return
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not calculate root of latest block header: "+err.Error(), http.StatusInternalServerError)
return
}
isFinalized := s.FinalizationFetcher.IsFinalized(ctx, blockRoot)
rawIds := r.URL.Query()["id"]
ids, ok := decodeIds(w, st, rawIds, true /* ignore unknown */)
if !ok {
return
}
// return no data if all IDs are ignored
if len(rawIds) > 0 && len(ids) == 0 {
resp := &GetValidatorsResponse{
Data: []*ValidatorContainer{},
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
return
}
readOnlyVals, ok := valsFromIds(w, st, ids)
if !ok {
return
}
epoch := slots.ToEpoch(st.Slot())
allBalances := st.Balances()
statuses := r.URL.Query()["status"]
for i, ss := range statuses {
statuses[i] = strings.ToLower(ss)
}
// Exit early if no matching validators were found or we don't want to further filter validators by status.
if len(readOnlyVals) == 0 || len(statuses) == 0 {
containers := make([]*ValidatorContainer, len(readOnlyVals))
for i, val := range readOnlyVals {
valStatus, err := helpers.ValidatorSubStatus(val, epoch)
if err != nil {
http2.HandleError(w, "Could not get validator status: "+err.Error(), http.StatusInternalServerError)
return
}
if len(ids) == 0 {
containers[i] = valContainerFromReadOnlyVal(val, primitives.ValidatorIndex(i), allBalances[i], valStatus)
} else {
containers[i] = valContainerFromReadOnlyVal(val, ids[i], allBalances[ids[i]], valStatus)
}
}
resp := &GetValidatorsResponse{
Data: containers,
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
return
}
filteredStatuses := make(map[validator.ValidatorStatus]bool, len(statuses))
for _, ss := range statuses {
ok, vs := validator.ValidatorStatusFromString(ss)
if !ok {
http2.HandleError(w, "Invalid status "+ss, http.StatusBadRequest)
return
}
filteredStatuses[vs] = true
}
valContainers := make([]*ValidatorContainer, 0, len(readOnlyVals))
for i, val := range readOnlyVals {
valStatus, err := helpers.ValidatorStatus(val, epoch)
if err != nil {
http2.HandleError(w, "Could not get validator status: "+err.Error(), http.StatusInternalServerError)
return
}
valSubStatus, err := helpers.ValidatorSubStatus(val, epoch)
if err != nil {
http2.HandleError(w, "Could not get validator status: "+err.Error(), http.StatusInternalServerError)
return
}
if filteredStatuses[valStatus] || filteredStatuses[valSubStatus] {
var container *ValidatorContainer
if len(ids) == 0 {
container = valContainerFromReadOnlyVal(val, primitives.ValidatorIndex(i), allBalances[i], valSubStatus)
} else {
container = valContainerFromReadOnlyVal(val, ids[i], allBalances[ids[i]], valSubStatus)
}
valContainers = append(valContainers, container)
}
}
resp := &GetValidatorsResponse{
Data: valContainers,
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
}
// GetValidator returns a validator specified by state and id or public key along with status and balance.
func (s *Server) GetValidator(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetValidator")
defer span.End()
stateId := mux.Vars(r)["state_id"]
if stateId == "" {
http2.HandleError(w, "state_id is required in URL params", http.StatusBadRequest)
return
}
valId := mux.Vars(r)["validator_id"]
if valId == "" {
http2.HandleError(w, "validator_id is required in URL params", http.StatusBadRequest)
return
}
st, err := s.Stater.State(ctx, []byte(stateId))
if err != nil {
shared.WriteStateFetchError(w, err)
return
}
ids, ok := decodeIds(w, st, []string{valId}, false /* ignore unknown */)
if !ok {
return
}
readOnlyVals, ok := valsFromIds(w, st, ids)
if !ok {
return
}
if len(ids) == 0 || len(readOnlyVals) == 0 {
http2.HandleError(w, "No validator returned for the given ID", http.StatusInternalServerError)
return
}
valSubStatus, err := helpers.ValidatorSubStatus(readOnlyVals[0], slots.ToEpoch(st.Slot()))
if err != nil {
http2.HandleError(w, "Could not get validator status: "+err.Error(), http.StatusInternalServerError)
return
}
bal, err := st.BalanceAtIndex(ids[0])
if err != nil {
http2.HandleError(w, "Could not get validator balance: "+err.Error(), http.StatusInternalServerError)
return
}
container := valContainerFromReadOnlyVal(readOnlyVals[0], ids[0], bal, valSubStatus)
isOptimistic, err := helpers.IsOptimistic(ctx, []byte(stateId), s.OptimisticModeFetcher, s.Stater, s.ChainInfoFetcher, s.BeaconDB)
if err != nil {
http2.HandleError(w, "Could not check optimistic status: "+err.Error(), http.StatusInternalServerError)
return
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not calculate root of latest block header: "+err.Error(), http.StatusInternalServerError)
return
}
isFinalized := s.FinalizationFetcher.IsFinalized(ctx, blockRoot)
resp := &GetValidatorResponse{
Data: container,
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
}
// GetValidatorBalances returns a filterable list of validator balances.
func (bs *Server) GetValidatorBalances(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetValidatorBalances")
defer span.End()
stateId := mux.Vars(r)["state_id"]
if stateId == "" {
http2.HandleError(w, "state_id is required in URL params", http.StatusBadRequest)
return
}
st, err := bs.Stater.State(ctx, []byte(stateId))
if err != nil {
shared.WriteStateFetchError(w, err)
return
}
isOptimistic, err := helpers.IsOptimistic(ctx, []byte(stateId), bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
http2.HandleError(w, "Could not check optimistic status: "+err.Error(), http.StatusInternalServerError)
return
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
http2.HandleError(w, "Could not calculate root of latest block header: "+err.Error(), http.StatusInternalServerError)
return
}
isFinalized := bs.FinalizationFetcher.IsFinalized(ctx, blockRoot)
rawIds := r.URL.Query()["id"]
ids, ok := decodeIds(w, st, rawIds, true /* ignore unknown */)
if !ok {
return
}
// return no data if all IDs are ignored
if len(rawIds) > 0 && len(ids) == 0 {
resp := &GetValidatorBalancesResponse{
Data: []*ValidatorBalance{},
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
return
}
bals := st.Balances()
var valBalances []*ValidatorBalance
if len(ids) == 0 {
valBalances = make([]*ValidatorBalance, len(bals))
for i, b := range bals {
valBalances[i] = &ValidatorBalance{
Index: strconv.FormatUint(uint64(i), 10),
Balance: strconv.FormatUint(b, 10),
}
}
} else {
valBalances = make([]*ValidatorBalance, len(ids))
for i, id := range ids {
valBalances[i] = &ValidatorBalance{
Index: strconv.FormatUint(uint64(id), 10),
Balance: strconv.FormatUint(bals[id], 10),
}
}
}
resp := &GetValidatorBalancesResponse{
Data: valBalances,
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}
http2.WriteJson(w, resp)
}
// decodeIds takes in a list of validator ID strings (as either a pubkey or a validator index)
// and returns the corresponding validator indices. It can be configured to ignore well-formed but unknown indices.
func decodeIds(w http.ResponseWriter, st state.BeaconState, rawIds []string, ignoreUnknown bool) ([]primitives.ValidatorIndex, bool) {
ids := make([]primitives.ValidatorIndex, 0, len(rawIds))
numVals := uint64(st.NumValidators())
for _, rawId := range rawIds {
pubkey, err := hexutil.Decode(rawId)
if err == nil {
if len(pubkey) != fieldparams.BLSPubkeyLength {
http2.HandleError(w, fmt.Sprintf("Pubkey length is %d instead of %d", len(pubkey), fieldparams.BLSPubkeyLength), http.StatusBadRequest)
return nil, false
}
valIndex, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubkey))
if !ok {
if ignoreUnknown {
continue
}
http2.HandleError(w, fmt.Sprintf("Unknown pubkey %s", pubkey), http.StatusBadRequest)
return nil, false
}
ids = append(ids, valIndex)
continue
}
index, err := strconv.ParseUint(rawId, 10, 64)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Invalid validator index %s", rawId), http.StatusBadRequest)
return nil, false
}
if index >= numVals {
if ignoreUnknown {
continue
}
http2.HandleError(w, fmt.Sprintf("Invalid validator index %d", index), http.StatusBadRequest)
return nil, false
}
ids = append(ids, primitives.ValidatorIndex(index))
}
return ids, true
}
// valsFromIds returns read-only validators based on the supplied validator indices.
func valsFromIds(w http.ResponseWriter, st state.BeaconState, ids []primitives.ValidatorIndex) ([]state.ReadOnlyValidator, bool) {
var vals []state.ReadOnlyValidator
if len(ids) == 0 {
allVals := st.Validators()
vals = make([]state.ReadOnlyValidator, len(allVals))
for i, val := range allVals {
readOnlyVal, err := statenative.NewValidator(val)
if err != nil {
http2.HandleError(w, "Could not convert validator: "+err.Error(), http.StatusInternalServerError)
return nil, false
}
vals[i] = readOnlyVal
}
} else {
vals = make([]state.ReadOnlyValidator, 0, len(ids))
for _, id := range ids {
val, err := st.ValidatorAtIndex(id)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not get validator at index %d: %s", id, err.Error()), http.StatusInternalServerError)
return nil, false
}
readOnlyVal, err := statenative.NewValidator(val)
if err != nil {
http2.HandleError(w, "Could not convert validator: "+err.Error(), http.StatusInternalServerError)
return nil, false
}
vals = append(vals, readOnlyVal)
}
}
return vals, true
}
func valContainerFromReadOnlyVal(
val state.ReadOnlyValidator,
id primitives.ValidatorIndex,
bal uint64,
valStatus validator.ValidatorStatus,
) *ValidatorContainer {
pubkey := val.PublicKey()
return &ValidatorContainer{
Index: strconv.FormatUint(uint64(id), 10),
Balance: strconv.FormatUint(bal, 10),
Status: valStatus.String(),
Validator: &Validator{
Pubkey: hexutil.Encode(pubkey[:]),
WithdrawalCredentials: hexutil.Encode(val.WithdrawalCredentials()),
EffectiveBalance: strconv.FormatUint(val.EffectiveBalance(), 10),
Slashed: val.Slashed(),
ActivationEligibilityEpoch: strconv.FormatUint(uint64(val.ActivationEligibilityEpoch()), 10),
ActivationEpoch: strconv.FormatUint(uint64(val.ActivationEpoch()), 10),
ExitEpoch: strconv.FormatUint(uint64(val.ExitEpoch()), 10),
WithdrawableEpoch: strconv.FormatUint(uint64(val.WithdrawableEpoch()), 10),
},
}
}

View File

@@ -0,0 +1,954 @@
package beacon
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/mux"
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
func TestGetValidators(t *testing.T) {
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
t.Run("get all", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 8192, len(resp.Data))
val := resp.Data[0]
assert.Equal(t, "0", val.Index)
assert.Equal(t, "32000000000", val.Balance)
assert.Equal(t, "active_ongoing", val.Status)
require.NotNil(t, val.Validator)
assert.Equal(t, "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c", val.Validator.Pubkey)
assert.Equal(t, "0x00ec7ef7780c9d151597924036262dd28dc60e1228f4da6fecf9d402cb3f3594", val.Validator.WithdrawalCredentials)
assert.Equal(t, "32000000000", val.Validator.EffectiveBalance)
assert.Equal(t, false, val.Validator.Slashed)
assert.Equal(t, "0", val.Validator.ActivationEligibilityEpoch)
assert.Equal(t, "0", val.Validator.ActivationEpoch)
assert.Equal(t, "18446744073709551615", val.Validator.ExitEpoch)
assert.Equal(t, "18446744073709551615", val.Validator.WithdrawableEpoch)
})
t.Run("get by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validators?id=15&id=26",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "15", resp.Data[0].Index)
assert.Equal(t, "26", resp.Data[1].Index)
})
t.Run("get by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey2 := st.PubkeyAtIndex(primitives.ValidatorIndex(66))
hexPubkey1 := hexutil.Encode(pubkey1[:])
hexPubkey2 := hexutil.Encode(pubkey2[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validators?id=%s&id=%s", hexPubkey1, hexPubkey2),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "20", resp.Data[0].Index)
assert.Equal(t, "66", resp.Data[1].Index)
})
t.Run("get by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
hexPubkey := hexutil.Encode(pubkey[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validators?id=%s&id=60", hexPubkey),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "20", resp.Data[0].Index)
assert.Equal(t, "60", resp.Data[1].Index)
})
t.Run("state ID required", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "state_id is required in URL params", e.Message)
})
t.Run("unknown pubkey is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey := st.PubkeyAtIndex(primitives.ValidatorIndex(1))
hexPubkey := hexutil.Encode(pubkey[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validators?id=%s&id=%s", hexPubkey, hexutil.Encode([]byte(strings.Repeat("x", fieldparams.BLSPubkeyLength)))),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, "1", resp.Data[0].Index)
})
t.Run("unknown index is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators?id=1&id=99999", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, "1", resp.Data[0].Index)
})
t.Run("execution optimistic", func(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
}
func TestListValidators_FilterByStatus(t *testing.T) {
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
farFutureEpoch := params.BeaconConfig().FarFutureEpoch
validators := []*eth.Validator{
// Pending initialized.
{
ActivationEpoch: farFutureEpoch,
ActivationEligibilityEpoch: farFutureEpoch,
},
// Pending queued.
{
ActivationEpoch: 10,
ActivationEligibilityEpoch: 4,
},
// Active ongoing.
{
ActivationEpoch: 0,
ExitEpoch: farFutureEpoch,
},
// Active slashed.
{
ActivationEpoch: 0,
ExitEpoch: 30,
Slashed: true,
},
// Active exiting.
{
ActivationEpoch: 3,
ExitEpoch: 30,
Slashed: false,
},
// Exited slashed (at epoch 35).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
Slashed: true,
},
// Exited unslashed (at epoch 35).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
Slashed: false,
},
// Withdrawable (at epoch 45).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
},
// Withdrawal done (at epoch 45).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
EffectiveBalance: 0,
Slashed: false,
},
}
for _, val := range validators {
require.NoError(t, st.AppendValidator(val))
require.NoError(t, st.AppendBalance(params.BeaconConfig().MaxEffectiveBalance))
}
t.Run("active", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators?status=active", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 8192+2, len(resp.Data))
for _, vc := range resp.Data {
assert.Equal(
t,
true,
vc.Status == "active_ongoing" ||
vc.Status == "active_exiting" ||
vc.Status == "active_slashed",
)
}
})
t.Run("active_ongoing", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators?status=active_ongoing", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 8192+1, len(resp.Data))
for _, vc := range resp.Data {
require.Equal(
t,
true,
vc.Status == "active_ongoing",
)
}
})
require.NoError(t, st.SetSlot(params.BeaconConfig().SlotsPerEpoch*35))
t.Run("exited", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators?status=exited", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 4, len(resp.Data))
for _, vc := range resp.Data {
require.Equal(
t,
true,
vc.Status == "exited_unslashed" || vc.Status == "exited_slashed",
)
}
})
t.Run("pending_initialized and exited_unslashed", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validators?status=pending_initialized&status=exited_unslashed",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 4, len(resp.Data))
for _, vc := range resp.Data {
require.Equal(
t,
true,
vc.Status == "pending_initialized" || vc.Status == "exited_unslashed",
)
}
})
t.Run("pending and exited_slashed", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validators?status=pending&status=exited_slashed",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, 2, len(resp.Data))
for _, vc := range resp.Data {
require.Equal(
t,
true,
vc.Status == "pending_initialized" || vc.Status == "exited_slashed",
)
}
})
}
func TestGetValidator(t *testing.T) {
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
t.Run("get by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": "15"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "15", resp.Data.Index)
assert.Equal(t, "32000000000", resp.Data.Balance)
assert.Equal(t, "active_ongoing", resp.Data.Status)
require.NotNil(t, resp.Data.Validator)
assert.Equal(t, "0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f", resp.Data.Validator.Pubkey)
assert.Equal(t, "0x00b24fc624e56a5ed42a9639691e27e34b783c7237030367bd17cbef65fa6ccf", resp.Data.Validator.WithdrawalCredentials)
assert.Equal(t, "32000000000", resp.Data.Validator.EffectiveBalance)
assert.Equal(t, false, resp.Data.Validator.Slashed)
assert.Equal(t, "0", resp.Data.Validator.ActivationEligibilityEpoch)
assert.Equal(t, "0", resp.Data.Validator.ActivationEpoch)
assert.Equal(t, "18446744073709551615", resp.Data.Validator.ExitEpoch)
assert.Equal(t, "18446744073709551615", resp.Data.Validator.WithdrawableEpoch)
})
t.Run("get by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubKey := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
hexPubkey := hexutil.Encode(pubKey[:])
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": hexPubkey})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "20", resp.Data.Index)
})
t.Run("state ID required", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"validator_id": "1"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "state_id is required in URL params", e.Message)
})
t.Run("validator ID required", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "validator_id is required in URL params", e.Message)
})
t.Run("unknown index", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": "99999"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "Invalid validator index", e.Message)
})
t.Run("unknown pubkey", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": hexutil.Encode([]byte(strings.Repeat("x", fieldparams.BLSPubkeyLength)))})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "Unknown pubkey", e.Message)
})
t.Run("execution optimistic", func(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": "15"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validators/{validator_id}", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head", "validator_id": "15"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
}
func TestGetValidatorBalances(t *testing.T) {
var st state.BeaconState
count := uint64(8192)
st, _ = util.DeterministicGenesisState(t, count)
balances := make([]uint64, count)
for i := uint64(0); i < count; i++ {
balances[i] = i
}
require.NoError(t, st.SetBalances(balances))
t.Run("get all", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validator_balances", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 8192, len(resp.Data))
val := resp.Data[123]
assert.Equal(t, "123", val.Index)
assert.Equal(t, "123", val.Balance)
})
t.Run("get by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=15&id=26",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "15", resp.Data[0].Index)
assert.Equal(t, "26", resp.Data[1].Index)
})
t.Run("get by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey2 := st.PubkeyAtIndex(primitives.ValidatorIndex(66))
hexPubkey1 := hexutil.Encode(pubkey1[:])
hexPubkey2 := hexutil.Encode(pubkey2[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=%s&id=%s", hexPubkey1, hexPubkey2),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "20", resp.Data[0].Index)
assert.Equal(t, "66", resp.Data[1].Index)
})
t.Run("get by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
hexPubkey := hexutil.Encode(pubkey[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validators?id=%s&id=60", hexPubkey),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidators(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 2, len(resp.Data))
assert.Equal(t, "20", resp.Data[0].Index)
assert.Equal(t, "60", resp.Data[1].Index)
})
t.Run("unknown pubkey is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
pubkey := st.PubkeyAtIndex(primitives.ValidatorIndex(1))
hexPubkey := hexutil.Encode(pubkey[:])
request := httptest.NewRequest(
http.MethodGet,
fmt.Sprintf("http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=%s&id=%s", hexPubkey, hexutil.Encode([]byte(strings.Repeat("x", fieldparams.BLSPubkeyLength)))),
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, "1", resp.Data[0].Index)
})
t.Run("unknown index is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=1&id=99999", nil)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, "1", resp.Data[0].Index)
})
t.Run("state ID required", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
}
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/validator_balances", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidator(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "state_id is required in URL params", e.Message)
})
t.Run("execution optimistic", func(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=15",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
request := httptest.NewRequest(
http.MethodGet,
"http://example.com/eth/v1/beacon/states/{state_id}/validator_balances?id=15",
nil,
)
request = mux.SetURLVars(request, map[string]string{"state_id": "head"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetValidatorBalances(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetValidatorBalancesResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, true, resp.Finalized)
})
}

View File

@@ -1,7 +1,6 @@
package beacon
import (
"bytes"
"context"
"strconv"
@@ -12,13 +11,10 @@ import (
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
eth2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"go.opencensus.io/trace"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
)
type stateRequest struct {
@@ -26,33 +22,6 @@ type stateRequest struct {
stateId []byte
}
// GetGenesis retrieves details of the chain's genesis which can be used to identify chain.
func (bs *Server) GetGenesis(ctx context.Context, _ *emptypb.Empty) (*ethpb.GenesisResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.GetGenesis")
defer span.End()
genesisTime := bs.GenesisTimeFetcher.GenesisTime()
if genesisTime.IsZero() {
return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
}
validatorRoot := bs.ChainInfoFetcher.GenesisValidatorsRoot()
if bytes.Equal(validatorRoot[:], params.BeaconConfig().ZeroHash[:]) {
return nil, status.Errorf(codes.NotFound, "Chain genesis info is not yet known")
}
forkVersion := params.BeaconConfig().GenesisForkVersion
return &ethpb.GenesisResponse{
Data: &ethpb.GenesisResponse_Genesis{
GenesisTime: &timestamppb.Timestamp{
Seconds: genesisTime.Unix(),
Nanos: 0,
},
GenesisValidatorsRoot: validatorRoot[:],
GenesisForkVersion: forkVersion,
},
}, nil
}
// GetStateRoot calculates HashTreeRoot for state with given 'stateId'. If stateId is root, same value will be returned.
func (bs *Server) GetStateRoot(ctx context.Context, req *ethpb.StateRequest) (*ethpb.StateRootResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.GetStateRoot")
@@ -90,37 +59,6 @@ func (bs *Server) GetStateRoot(ctx context.Context, req *ethpb.StateRequest) (*e
}, nil
}
// GetFinalityCheckpoints returns finality checkpoints for state with given 'stateId'. In case finality is
// not yet achieved, checkpoint should return epoch 0 and ZERO_HASH as root.
func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRequest) (*ethpb.StateFinalityCheckpointResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.GetFinalityCheckpoints")
defer span.End()
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not calculate root of latest block header")
}
isFinalized := bs.FinalizationFetcher.IsFinalized(ctx, blockRoot)
return &ethpb.StateFinalityCheckpointResponse{
Data: &ethpb.StateFinalityCheckpointResponse_StateFinalityCheckpoint{
PreviousJustified: checkpoint(st.PreviousJustifiedCheckpoint()),
CurrentJustified: checkpoint(st.CurrentJustifiedCheckpoint()),
Finalized: checkpoint(st.FinalizedCheckpoint()),
},
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
}, nil
}
// GetRandao fetches the RANDAO mix for the requested epoch from the state identified by state_id.
// If an epoch is not specified then the RANDAO mix for the state's current epoch will be returned.
// By adjusting the state_id parameter you can query for any historic value of the RANDAO mix.
@@ -197,16 +135,3 @@ func (bs *Server) stateFromRequest(ctx context.Context, req *stateRequest) (stat
}
return st, nil
}
func checkpoint(sourceCheckpoint *eth.Checkpoint) *ethpb.Checkpoint {
if sourceCheckpoint != nil {
return &ethpb.Checkpoint{
Epoch: sourceCheckpoint.Epoch,
Root: sourceCheckpoint.Root,
}
}
return &ethpb.Checkpoint{
Epoch: 0,
Root: params.BeaconConfig().ZeroHash[:],
}
}

View File

@@ -3,7 +3,6 @@ package beacon
import (
"context"
"testing"
"time"
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
@@ -13,66 +12,11 @@ import (
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
eth "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
eth2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
"google.golang.org/protobuf/types/known/emptypb"
)
func TestGetGenesis(t *testing.T) {
ctx := context.Background()
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig().Copy()
config.GenesisForkVersion = []byte("genesis")
params.OverrideBeaconConfig(config)
genesis := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)
validatorsRoot := [32]byte{1, 2, 3, 4, 5, 6}
t.Run("OK", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: genesis,
ValidatorsRoot: validatorsRoot,
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
resp, err := s.GetGenesis(ctx, &emptypb.Empty{})
require.NoError(t, err)
assert.Equal(t, genesis.Unix(), resp.Data.GenesisTime.Seconds)
assert.Equal(t, int32(0), resp.Data.GenesisTime.Nanos)
assert.DeepEqual(t, validatorsRoot[:], resp.Data.GenesisValidatorsRoot)
assert.DeepEqual(t, []byte("genesis"), resp.Data.GenesisForkVersion)
})
t.Run("No genesis time", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: time.Time{},
ValidatorsRoot: validatorsRoot,
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
assert.ErrorContains(t, "Chain genesis info is not yet known", err)
})
t.Run("No genesis validators root", func(t *testing.T) {
chainService := &chainMock.ChainService{
Genesis: genesis,
ValidatorsRoot: [32]byte{},
}
s := Server{
GenesisTimeFetcher: chainService,
ChainInfoFetcher: chainService,
}
_, err := s.GetGenesis(ctx, &emptypb.Empty{})
assert.ErrorContains(t, "Chain genesis info is not yet known", err)
})
}
func TestGetStateRoot(t *testing.T) {
ctx := context.Background()
fakeState, err := util.NewBeaconState()
@@ -163,111 +107,6 @@ func TestGetStateRoot(t *testing.T) {
})
}
func TestGetFinalityCheckpoints(t *testing.T) {
ctx := context.Background()
fillCheckpoints := func(state *ethpb.BeaconState) error {
state.PreviousJustifiedCheckpoint = &ethpb.Checkpoint{
Root: bytesutil.PadTo([]byte("previous"), 32),
Epoch: 113,
}
state.CurrentJustifiedCheckpoint = &ethpb.Checkpoint{
Root: bytesutil.PadTo([]byte("current"), 32),
Epoch: 123,
}
state.FinalizedCheckpoint = &ethpb.Checkpoint{
Root: bytesutil.PadTo([]byte("finalized"), 32),
Epoch: 103,
}
return nil
}
fakeState, err := util.NewBeaconState(fillCheckpoints)
require.NoError(t, err)
db := dbTest.SetupDB(t)
chainService := &chainMock.ChainService{}
server := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := server.GetFinalityCheckpoints(ctx, &eth.StateRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.Equal(t, fakeState.FinalizedCheckpoint().Epoch, resp.Data.Finalized.Epoch)
assert.DeepEqual(t, fakeState.FinalizedCheckpoint().Root, resp.Data.Finalized.Root)
assert.Equal(t, fakeState.CurrentJustifiedCheckpoint().Epoch, resp.Data.CurrentJustified.Epoch)
assert.DeepEqual(t, fakeState.CurrentJustifiedCheckpoint().Root, resp.Data.CurrentJustified.Root)
assert.Equal(t, fakeState.PreviousJustifiedCheckpoint().Epoch, resp.Data.PreviousJustified.Epoch)
assert.DeepEqual(t, fakeState.PreviousJustifiedCheckpoint().Root, resp.Data.PreviousJustified.Root)
t.Run("execution optimistic", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
chainService := &chainMock.ChainService{Optimistic: true}
server := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := server.GetFinalityCheckpoints(context.Background(), &eth.StateRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
headerRoot, err := fakeState.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
server := &Server{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := server.GetFinalityCheckpoints(context.Background(), &eth.StateRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, true, resp.Finalized)
})
}
func TestGetRandao(t *testing.T) {
mixCurrent := bytesutil.PadTo([]byte("current"), 32)
mixOld := bytesutil.PadTo([]byte("old"), 32)

View File

@@ -46,3 +46,78 @@ type GetStateForkResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type GetFinalityCheckpointsResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data *FinalityCheckpoints `json:"data"`
}
type FinalityCheckpoints struct {
PreviousJustified *shared.Checkpoint `json:"previous_justified"`
CurrentJustified *shared.Checkpoint `json:"current_justified"`
Finalized *shared.Checkpoint `json:"finalized"`
}
type GetGenesisResponse struct {
Data *Genesis `json:"data"`
}
type Genesis struct {
GenesisTime string `json:"genesis_time"`
GenesisValidatorsRoot string `json:"genesis_validators_root"`
GenesisForkVersion string `json:"genesis_fork_version"`
}
type GetBlockHeadersResponse struct {
Data []*shared.SignedBeaconBlockHeaderContainer `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type GetBlockHeaderResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data *shared.SignedBeaconBlockHeaderContainer `json:"data"`
}
type GetValidatorsResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data []*ValidatorContainer `json:"data"`
}
type GetValidatorResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data *ValidatorContainer `json:"data"`
}
type GetValidatorBalancesResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data []*ValidatorBalance `json:"data"`
}
type ValidatorContainer struct {
Index string `json:"index"`
Balance string `json:"balance"`
Status string `json:"status"`
Validator *Validator `json:"validator"`
}
type Validator struct {
Pubkey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
EffectiveBalance string `json:"effective_balance"`
Slashed bool `json:"slashed"`
ActivationEligibilityEpoch string `json:"activation_eligibility_epoch"`
ActivationEpoch string `json:"activation_epoch"`
ExitEpoch string `json:"exit_epoch"`
WithdrawableEpoch string `json:"withdrawable_epoch"`
}
type ValidatorBalance struct {
Index string `json:"index"`
Balance string `json:"balance"`
}

View File

@@ -1,253 +0,0 @@
package beacon
import (
"context"
"strconv"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
statenative "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"go.opencensus.io/trace"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// invalidValidatorIdError represents an error scenario where a validator's ID is invalid.
type invalidValidatorIdError struct {
message string
}
// newInvalidValidatorIdError creates a new error instance.
func newInvalidValidatorIdError(validatorId []byte, reason error) invalidValidatorIdError {
return invalidValidatorIdError{
message: errors.Wrapf(reason, "could not decode validator id '%s'", string(validatorId)).Error(),
}
}
// Error returns the underlying error message.
func (e *invalidValidatorIdError) Error() string {
return e.message
}
// GetValidator returns a validator specified by state and id or public key along with status and balance.
func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorRequest) (*ethpb.StateValidatorResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.GetValidator")
defer span.End()
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
if len(req.ValidatorId) == 0 {
return nil, status.Error(codes.InvalidArgument, "Validator ID is required")
}
valContainer, err := valContainersByRequestIds(st, [][]byte{req.ValidatorId})
if err != nil {
return nil, handleValContainerErr(err)
}
if len(valContainer) == 0 {
return nil, status.Error(codes.NotFound, "Could not find validator")
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not calculate root of latest block header")
}
isFinalized := bs.FinalizationFetcher.IsFinalized(ctx, blockRoot)
return &ethpb.StateValidatorResponse{Data: valContainer[0], ExecutionOptimistic: isOptimistic, Finalized: isFinalized}, nil
}
// ListValidators returns filterable list of validators with their balance, status and index.
func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidatorsRequest) (*ethpb.StateValidatorsResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.ListValidators")
defer span.End()
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
valContainers, err := valContainersByRequestIds(st, req.Id)
if err != nil {
return nil, handleValContainerErr(err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not calculate root of latest block header")
}
isFinalized := bs.FinalizationFetcher.IsFinalized(ctx, blockRoot)
// Exit early if no matching validators we found or we don't want to further filter validators by status.
if len(valContainers) == 0 || len(req.Status) == 0 {
return &ethpb.StateValidatorsResponse{Data: valContainers, ExecutionOptimistic: isOptimistic, Finalized: isFinalized}, nil
}
filterStatus := make(map[validator.ValidatorStatus]bool, len(req.Status))
const lastValidStatusValue = 12
for _, ss := range req.Status {
if ss > lastValidStatusValue {
return nil, status.Errorf(codes.InvalidArgument, "Invalid status "+ss.String())
}
filterStatus[validator.ValidatorStatus(ss)] = true
}
epoch := slots.ToEpoch(st.Slot())
filteredVals := make([]*ethpb.ValidatorContainer, 0, len(valContainers))
for _, vc := range valContainers {
readOnlyVal, err := statenative.NewValidator(migration.V1ValidatorToV1Alpha1(vc.Validator))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
}
valStatus, err := helpers.ValidatorStatus(readOnlyVal, epoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get validator status: %v", err)
}
valSubStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get validator sub status: %v", err)
}
if filterStatus[valStatus] || filterStatus[valSubStatus] {
filteredVals = append(filteredVals, vc)
}
}
return &ethpb.StateValidatorsResponse{Data: filteredVals, ExecutionOptimistic: isOptimistic, Finalized: isFinalized}, nil
}
// ListValidatorBalances returns a filterable list of validator balances.
func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.ValidatorBalancesRequest) (*ethpb.ValidatorBalancesResponse, error) {
ctx, span := trace.StartSpan(ctx, "beacon.ListValidatorBalances")
defer span.End()
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
valContainers, err := valContainersByRequestIds(st, req.Id)
if err != nil {
return nil, handleValContainerErr(err)
}
valBalances := make([]*ethpb.ValidatorBalance, len(valContainers))
for i := 0; i < len(valContainers); i++ {
valBalances[i] = &ethpb.ValidatorBalance{
Index: valContainers[i].Index,
Balance: valContainers[i].Balance,
}
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not calculate root of latest block header")
}
isFinalized := bs.FinalizationFetcher.IsFinalized(ctx, blockRoot)
return &ethpb.ValidatorBalancesResponse{Data: valBalances, ExecutionOptimistic: isOptimistic, Finalized: isFinalized}, nil
}
// This function returns the validator object based on the passed in ID. The validator ID could be its public key,
// or its index.
func valContainersByRequestIds(state state.BeaconState, validatorIds [][]byte) ([]*ethpb.ValidatorContainer, error) {
epoch := slots.ToEpoch(state.Slot())
var valContainers []*ethpb.ValidatorContainer
allBalances := state.Balances()
if len(validatorIds) == 0 {
allValidators := state.Validators()
valContainers = make([]*ethpb.ValidatorContainer, len(allValidators))
for i, val := range allValidators {
readOnlyVal, err := statenative.NewValidator(val)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
}
subStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
if err != nil {
return nil, errors.Wrap(err, "could not get validator sub status")
}
valContainers[i] = &ethpb.ValidatorContainer{
Index: primitives.ValidatorIndex(i),
Balance: allBalances[i],
Status: ethpb.ValidatorStatus(subStatus),
Validator: migration.V1Alpha1ValidatorToV1(val),
}
}
} else {
valContainers = make([]*ethpb.ValidatorContainer, 0, len(validatorIds))
for _, validatorId := range validatorIds {
var valIndex primitives.ValidatorIndex
if len(validatorId) == params.BeaconConfig().BLSPubkeyLength {
var ok bool
valIndex, ok = state.ValidatorIndexByPubkey(bytesutil.ToBytes48(validatorId))
if !ok {
// Ignore well-formed yet unknown public keys.
continue
}
} else {
index, err := strconv.ParseUint(string(validatorId), 10, 64)
if err != nil {
e := newInvalidValidatorIdError(validatorId, err)
return nil, &e
}
valIndex = primitives.ValidatorIndex(index)
}
val, err := state.ValidatorAtIndex(valIndex)
if _, ok := err.(*statenative.ValidatorIndexOutOfRangeError); ok {
// Ignore well-formed yet unknown indexes.
continue
}
if err != nil {
return nil, errors.Wrap(err, "could not get validator")
}
v1Validator := migration.V1Alpha1ValidatorToV1(val)
readOnlyVal, err := statenative.NewValidator(val)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
}
subStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
if err != nil {
return nil, errors.Wrap(err, "could not get validator sub status")
}
valContainers = append(valContainers, &ethpb.ValidatorContainer{
Index: valIndex,
Balance: allBalances[valIndex],
Status: ethpb.ValidatorStatus(subStatus),
Validator: v1Validator,
})
}
}
return valContainers, nil
}
func handleValContainerErr(err error) error {
if outOfRangeErr, ok := err.(*statenative.ValidatorIndexOutOfRangeError); ok {
return status.Errorf(codes.InvalidArgument, "Invalid validator ID: %v", outOfRangeErr)
}
if invalidIdErr, ok := err.(*invalidValidatorIdError); ok {
return status.Errorf(codes.InvalidArgument, "Invalid validator ID: %v", invalidIdErr)
}
return status.Errorf(codes.Internal, "Could not get validator container: %v", err)
}

View File

@@ -1,782 +0,0 @@
package beacon
import (
"bytes"
"context"
"strings"
"testing"
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
func TestGetValidator(t *testing.T) {
ctx := context.Background()
db := dbTest.SetupDB(t)
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
t.Run("Head Get Validator by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.GetValidator(ctx, &ethpb.StateValidatorRequest{
StateId: []byte("head"),
ValidatorId: []byte("15"),
})
require.NoError(t, err)
assert.Equal(t, primitives.ValidatorIndex(15), resp.Data.Index)
})
t.Run("Head Get Validator by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
pubKey := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
resp, err := s.GetValidator(ctx, &ethpb.StateValidatorRequest{
StateId: []byte("head"),
ValidatorId: pubKey[:],
})
require.NoError(t, err)
assert.Equal(t, primitives.ValidatorIndex(20), resp.Data.Index)
assert.Equal(t, true, bytes.Equal(pubKey[:], resp.Data.Validator.Pubkey))
})
t.Run("Validator ID required", func(t *testing.T) {
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
BeaconDB: db,
}
_, err := s.GetValidator(ctx, &ethpb.StateValidatorRequest{
StateId: []byte("head"),
})
require.ErrorContains(t, "Validator ID is required", err)
})
t.Run("execution optimistic", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.GetValidator(ctx, &ethpb.StateValidatorRequest{
StateId: []byte("head"),
ValidatorId: []byte("15"),
})
require.NoError(t, err)
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.GetValidator(ctx, &ethpb.StateValidatorRequest{
StateId: []byte("head"),
ValidatorId: []byte("15"),
})
require.NoError(t, err)
assert.Equal(t, true, resp.Finalized)
})
}
func TestListValidators(t *testing.T) {
ctx := context.Background()
db := dbTest.SetupDB(t)
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
t.Run("Head List All Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.Equal(t, len(resp.Data), 8192)
for _, val := range resp.Data {
assert.Equal(t, ethpb.ValidatorStatus_ACTIVE_ONGOING, val.Status)
}
})
t.Run("Head List Validators by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
ids := [][]byte{[]byte("15"), []byte("26"), []byte("400")}
idNums := []primitives.ValidatorIndex{15, 26, 400}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, ethpb.ValidatorStatus_ACTIVE_ONGOING, val.Status)
}
})
t.Run("Head List Validators by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
idNums := []primitives.ValidatorIndex{20, 66, 90, 100}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey2 := st.PubkeyAtIndex(primitives.ValidatorIndex(66))
pubkey3 := st.PubkeyAtIndex(primitives.ValidatorIndex(90))
pubkey4 := st.PubkeyAtIndex(primitives.ValidatorIndex(100))
pubKeys := [][]byte{pubkey1[:], pubkey2[:], pubkey3[:], pubkey4[:]}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Id: pubKeys,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, true, bytes.Equal(pubKeys[i], val.Validator.Pubkey))
assert.Equal(t, ethpb.ValidatorStatus_ACTIVE_ONGOING, val.Status)
}
})
t.Run("Head List Validators by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
idNums := []primitives.ValidatorIndex{20, 90, 170, 129}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey2 := st.PubkeyAtIndex(primitives.ValidatorIndex(90))
pubkey3 := st.PubkeyAtIndex(primitives.ValidatorIndex(170))
pubkey4 := st.PubkeyAtIndex(primitives.ValidatorIndex(129))
pubkeys := [][]byte{pubkey1[:], pubkey2[:], pubkey3[:], pubkey4[:]}
ids := [][]byte{pubkey1[:], []byte("90"), pubkey3[:], []byte("129")}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, true, bytes.Equal(pubkeys[i], val.Validator.Pubkey))
assert.Equal(t, ethpb.ValidatorStatus_ACTIVE_ONGOING, val.Status)
}
})
t.Run("Unknown public key is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
existingKey := st.PubkeyAtIndex(primitives.ValidatorIndex(1))
pubkeys := [][]byte{existingKey[:], []byte(strings.Repeat("f", 48))}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Id: pubkeys,
})
require.NoError(t, err)
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, primitives.ValidatorIndex(1), resp.Data[0].Index)
})
t.Run("Unknown index is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
ids := [][]byte{[]byte("1"), []byte("99999")}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
require.Equal(t, 1, len(resp.Data))
assert.Equal(t, primitives.ValidatorIndex(1), resp.Data[0].Index)
})
t.Run("execution optimistic", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
})
require.NoError(t, err)
assert.Equal(t, true, resp.Finalized)
})
}
func TestListValidators_Status(t *testing.T) {
ctx := context.Background()
db := dbTest.SetupDB(t)
var st state.BeaconState
st, _ = util.DeterministicGenesisState(t, 8192)
farFutureEpoch := params.BeaconConfig().FarFutureEpoch
validators := []*eth.Validator{
// Pending initialized.
{
ActivationEpoch: farFutureEpoch,
ActivationEligibilityEpoch: farFutureEpoch,
},
// Pending queued.
{
ActivationEpoch: 10,
ActivationEligibilityEpoch: 4,
},
// Active ongoing.
{
ActivationEpoch: 0,
ExitEpoch: farFutureEpoch,
},
// Active slashed.
{
ActivationEpoch: 0,
ExitEpoch: 30,
Slashed: true,
},
// Active exiting.
{
ActivationEpoch: 3,
ExitEpoch: 30,
Slashed: false,
},
// Exit slashed (at epoch 35).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
Slashed: true,
},
// Exit unslashed (at epoch 35).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
Slashed: false,
},
// Withdrawable (at epoch 45).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
},
// Withdrawal done (at epoch 45).
{
ActivationEpoch: 3,
ExitEpoch: 30,
WithdrawableEpoch: 40,
EffectiveBalance: 0,
Slashed: false,
},
}
for _, validator := range validators {
require.NoError(t, st.AppendValidator(validator))
require.NoError(t, st.AppendBalance(params.BeaconConfig().MaxEffectiveBalance))
}
t.Run("Head List All ACTIVE Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Status: []ethpb.ValidatorStatus{ethpb.ValidatorStatus_ACTIVE},
})
require.NoError(t, err)
assert.Equal(t, len(resp.Data), 8192+2 /* 2 active */)
for _, datum := range resp.Data {
readOnlyVal, err := state_native.NewValidator(migration.V1ValidatorToV1Alpha1(datum.Validator))
require.NoError(t, err)
status, err := rpchelpers.ValidatorStatus(readOnlyVal, 0)
require.NoError(t, err)
require.Equal(
t,
true,
status == validator.Active,
)
require.Equal(
t,
true,
datum.Status == ethpb.ValidatorStatus_ACTIVE_ONGOING ||
datum.Status == ethpb.ValidatorStatus_ACTIVE_EXITING ||
datum.Status == ethpb.ValidatorStatus_ACTIVE_SLASHED,
)
}
})
t.Run("Head List All ACTIVE_ONGOING Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Status: []ethpb.ValidatorStatus{ethpb.ValidatorStatus_ACTIVE_ONGOING},
})
require.NoError(t, err)
assert.Equal(t, len(resp.Data), 8192+1 /* 1 active_ongoing */)
for _, datum := range resp.Data {
readOnlyVal, err := state_native.NewValidator(migration.V1ValidatorToV1Alpha1(datum.Validator))
require.NoError(t, err)
status, err := rpchelpers.ValidatorSubStatus(readOnlyVal, 0)
require.NoError(t, err)
require.Equal(
t,
true,
status == validator.ActiveOngoing,
)
require.Equal(
t,
true,
datum.Status == ethpb.ValidatorStatus_ACTIVE_ONGOING,
)
}
})
require.NoError(t, st.SetSlot(params.BeaconConfig().SlotsPerEpoch*35))
t.Run("Head List All EXITED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Status: []ethpb.ValidatorStatus{ethpb.ValidatorStatus_EXITED},
})
require.NoError(t, err)
assert.Equal(t, 4 /* 4 exited */, len(resp.Data))
for _, datum := range resp.Data {
readOnlyVal, err := state_native.NewValidator(migration.V1ValidatorToV1Alpha1(datum.Validator))
require.NoError(t, err)
status, err := rpchelpers.ValidatorStatus(readOnlyVal, 35)
require.NoError(t, err)
require.Equal(
t,
true,
status == validator.Exited,
)
require.Equal(
t,
true,
datum.Status == ethpb.ValidatorStatus_EXITED_UNSLASHED || datum.Status == ethpb.ValidatorStatus_EXITED_SLASHED,
)
}
})
t.Run("Head List All PENDING_INITIALIZED and EXITED_UNSLASHED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Status: []ethpb.ValidatorStatus{ethpb.ValidatorStatus_PENDING_INITIALIZED, ethpb.ValidatorStatus_EXITED_UNSLASHED},
})
require.NoError(t, err)
assert.Equal(t, 4 /* 4 exited */, len(resp.Data))
for _, datum := range resp.Data {
readOnlyVal, err := state_native.NewValidator(migration.V1ValidatorToV1Alpha1(datum.Validator))
require.NoError(t, err)
status, err := rpchelpers.ValidatorSubStatus(readOnlyVal, 35)
require.NoError(t, err)
require.Equal(
t,
true,
status == validator.PendingInitialized || status == validator.ExitedUnslashed,
)
require.Equal(
t,
true,
datum.Status == ethpb.ValidatorStatus_PENDING_INITIALIZED || datum.Status == ethpb.ValidatorStatus_EXITED_UNSLASHED,
)
}
})
t.Run("Head List All PENDING and EXITED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
resp, err := s.ListValidators(ctx, &ethpb.StateValidatorsRequest{
StateId: []byte("head"),
Status: []ethpb.ValidatorStatus{ethpb.ValidatorStatus_PENDING, ethpb.ValidatorStatus_EXITED_SLASHED},
})
require.NoError(t, err)
assert.Equal(t, 2 /* 1 pending, 1 exited */, len(resp.Data))
for _, datum := range resp.Data {
readOnlyVal, err := state_native.NewValidator(migration.V1ValidatorToV1Alpha1(datum.Validator))
require.NoError(t, err)
status, err := rpchelpers.ValidatorStatus(readOnlyVal, 35)
require.NoError(t, err)
subStatus, err := rpchelpers.ValidatorSubStatus(readOnlyVal, 35)
require.NoError(t, err)
require.Equal(
t,
true,
status == validator.Pending || subStatus == validator.ExitedSlashed,
)
require.Equal(
t,
true,
datum.Status == ethpb.ValidatorStatus_PENDING_INITIALIZED || datum.Status == ethpb.ValidatorStatus_EXITED_SLASHED,
)
}
})
}
func TestListValidatorBalances(t *testing.T) {
ctx := context.Background()
db := dbTest.SetupDB(t)
var st state.BeaconState
count := uint64(8192)
st, _ = util.DeterministicGenesisState(t, count)
balances := make([]uint64, count)
for i := uint64(0); i < count; i++ {
balances[i] = i
}
require.NoError(t, st.SetBalances(balances))
t.Run("Head List Validators Balance by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
ids := [][]byte{[]byte("15"), []byte("26"), []byte("400")}
idNums := []primitives.ValidatorIndex{15, 26, 400}
resp, err := s.ListValidatorBalances(ctx, &ethpb.ValidatorBalancesRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, balances[val.Index], val.Balance)
}
})
t.Run("Head List Validators Balance by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
idNums := []primitives.ValidatorIndex{20, 66, 90, 100}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey2 := st.PubkeyAtIndex(primitives.ValidatorIndex(66))
pubkey3 := st.PubkeyAtIndex(primitives.ValidatorIndex(90))
pubkey4 := st.PubkeyAtIndex(primitives.ValidatorIndex(100))
pubKeys := [][]byte{pubkey1[:], pubkey2[:], pubkey3[:], pubkey4[:]}
resp, err := s.ListValidatorBalances(ctx, &ethpb.ValidatorBalancesRequest{
StateId: []byte("head"),
Id: pubKeys,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, balances[val.Index], val.Balance)
}
})
t.Run("Head List Validators Balance by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
idNums := []primitives.ValidatorIndex{20, 90, 170, 129}
pubkey1 := st.PubkeyAtIndex(primitives.ValidatorIndex(20))
pubkey3 := st.PubkeyAtIndex(primitives.ValidatorIndex(170))
ids := [][]byte{pubkey1[:], []byte("90"), pubkey3[:], []byte("129")}
resp, err := s.ListValidatorBalances(ctx, &ethpb.ValidatorBalancesRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
for i, val := range resp.Data {
assert.Equal(t, idNums[i], val.Index)
assert.Equal(t, balances[val.Index], val.Balance)
}
})
t.Run("execution optimistic", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
ids := [][]byte{[]byte("15"), []byte("26"), []byte("400")}
resp, err := s.ListValidatorBalances(ctx, &ethpb.ValidatorBalancesRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
parentRoot := [32]byte{'a'}
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
headerRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
chainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{
headerRoot: true,
},
}
s := Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
BeaconDB: db,
}
ids := [][]byte{[]byte("15"), []byte("26"), []byte("400")}
resp, err := s.ListValidatorBalances(ctx, &ethpb.ValidatorBalancesRequest{
StateId: []byte("head"),
Id: ids,
})
require.NoError(t, err)
assert.Equal(t, true, resp.Finalized)
})
}

View File

@@ -16,6 +16,7 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/eth/service:go_default_library",
"//proto/eth/v1:go_default_library",
@@ -38,6 +39,7 @@ go_test(
embed = [":go_default_library"],
deps = [
"//async/event:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/feed:go_default_library",
@@ -47,6 +49,7 @@ go_test(
"//beacon-chain/core/time:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/blocks:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/migration:go_default_library",

View File

@@ -5,12 +5,14 @@ import (
gwpb "github.com/grpc-ecosystem/grpc-gateway/v2/proto/gateway"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/operation"
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpbservice "github.com/prysmaticlabs/prysm/v4/proto/eth/service"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
@@ -43,6 +45,8 @@ const (
BLSToExecutionChangeTopic = "bls_to_execution_change"
// PayloadAttributesTopic represents a new payload attributes for execution payload building event topic.
PayloadAttributesTopic = "payload_attributes"
// BlobSidecarTopic represents a new blob sidecar event topic
BlobSidecarTopic = "blob_sidecar"
)
var casesHandled = map[string]bool{
@@ -55,6 +59,7 @@ var casesHandled = map[string]bool{
SyncCommitteeContributionTopic: true,
BLSToExecutionChangeTopic: true,
PayloadAttributesTopic: true,
BlobSidecarTopic: true,
}
// StreamEvents allows requesting all events from a set of topics defined in the Ethereum consensus API standard.
@@ -161,7 +166,26 @@ func handleBlockOperationEvents(
}
v2Change := migration.V1Alpha1SignedBLSToExecChangeToV2(changeData.Change)
return streamData(stream, BLSToExecutionChangeTopic, v2Change)
case operation.BlobSidecarReceived:
if _, ok := requestedTopics[BlobSidecarTopic]; !ok {
return nil
}
blobData, ok := event.Data.(*operation.BlobSidecarReceivedData)
if !ok {
return nil
}
if blobData == nil || blobData.Blob == nil {
return nil
}
versionedHash := blockchain.ConvertKzgCommitmentToVersionedHash(blobData.Blob.Message.KzgCommitment)
blobEvent := &ethpb.EventBlobSidecar{
BlockRoot: bytesutil.SafeCopyBytes(blobData.Blob.Message.BlockRoot),
Index: blobData.Blob.Message.Index,
Slot: blobData.Blob.Message.Slot,
VersionedHash: bytesutil.SafeCopyBytes(versionedHash.Bytes()),
KzgCommitment: bytesutil.SafeCopyBytes(blobData.Blob.Message.KzgCommitment),
}
return streamData(stream, BlobSidecarTopic, blobEvent)
default:
return nil
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/grpc-ecosystem/grpc-gateway/v2/proto/gateway"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v4/async/event"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
mockChain "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
b "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
@@ -19,6 +20,7 @@ import (
prysmtime "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/time"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
@@ -233,6 +235,52 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
feed: srv.OperationNotifier.OperationFeed(),
})
})
t.Run(BlobSidecarTopic, func(t *testing.T) {
ctx := context.Background()
srv, ctrl, mockStream := setupServer(ctx, t)
defer ctrl.Finish()
commitment, err := hexutil.Decode("0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000")
require.NoError(t, err)
wantedBlobV1alpha1 := &eth.SignedBlobSidecar{
Message: &eth.BlobSidecar{
BlockRoot: make([]byte, fieldparams.RootLength),
Index: 1,
Slot: 3,
KzgCommitment: commitment,
},
Signature: make([]byte, 96),
}
versionedHash := blockchain.ConvertKzgCommitmentToVersionedHash(commitment)
blobEvent := &ethpb.EventBlobSidecar{
BlockRoot: bytesutil.SafeCopyBytes(wantedBlobV1alpha1.Message.BlockRoot),
Index: wantedBlobV1alpha1.Message.Index,
Slot: wantedBlobV1alpha1.Message.Slot,
VersionedHash: bytesutil.SafeCopyBytes(versionedHash.Bytes()),
KzgCommitment: bytesutil.SafeCopyBytes(wantedBlobV1alpha1.Message.KzgCommitment),
}
genericResponse, err := anypb.New(blobEvent)
require.NoError(t, err)
wantedMessage := &gateway.EventSource{
Event: BlobSidecarTopic,
Data: genericResponse,
}
assertFeedSendAndReceive(ctx, &assertFeedArgs{
t: t,
srv: srv,
topics: []string{BlobSidecarTopic},
stream: mockStream,
shouldReceive: wantedMessage,
itemToSend: &feed.Event{
Type: operation.BlobSidecarReceived,
Data: &operation.BlobSidecarReceivedData{
Blob: wantedBlobV1alpha1,
},
},
feed: srv.OperationNotifier.OperationFeed(),
})
})
}
func TestStreamEvents_StateEvents(t *testing.T) {

View File

@@ -23,7 +23,6 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network/http:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",

View File

@@ -2,12 +2,9 @@ package helpers
import (
"errors"
"fmt"
"net/http"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
@@ -27,23 +24,6 @@ func PrepareStateFetchGRPCError(err error) error {
return status.Errorf(codes.Internal, "Invalid state ID: %v", err)
}
// HandleStateFetchError writes the appropriate HTTP error based on the supplied error.
func HandleStateFetchError(w http.ResponseWriter, err error) {
if errors.Is(err, stategen.ErrNoDataForSlot) {
http2.HandleError(w, "Lacking historical data needed to fulfill request", http.StatusNotFound)
return
}
if stateNotFoundErr, ok := err.(*lookup.StateNotFoundError); ok {
http2.HandleError(w, "State not found: "+stateNotFoundErr.Error(), http.StatusNotFound)
return
}
if parseErr, ok := err.(*lookup.StateIdParseError); ok {
http2.HandleError(w, "Invalid state ID: "+parseErr.Error(), http.StatusBadRequest)
return
}
http2.HandleError(w, "Invalid state ID: "+err.Error(), http.StatusInternalServerError)
}
// IndexedVerificationFailure represents a collection of verification failures.
type IndexedVerificationFailure struct {
Failures []*SingleIndexedVerificationFailure `json:"failures"`
@@ -54,15 +34,3 @@ type SingleIndexedVerificationFailure struct {
Index int `json:"index"`
Message string `json:"message"`
}
// PrepareStateFetchError returns an appropriate error based on the supplied argument.
// The argument error should be a result of fetching state.
func PrepareStateFetchError(err error) error {
if errors.Is(err, stategen.ErrNoDataForSlot) {
return errors.New("lacking historical data needed to fulfill request")
}
if stateNotFoundErr, ok := err.(*lookup.StateNotFoundError); ok {
return fmt.Errorf("state not found: %v", stateNotFoundErr)
}
return fmt.Errorf("could not fetch state: %v", err)
}

View File

@@ -13,8 +13,11 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/sync:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",

View File

@@ -2,7 +2,13 @@ package shared
import (
"fmt"
"net/http"
"strings"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
)
// DecodeError represents an error resulting from trying to decode an HTTP request.
@@ -43,3 +49,33 @@ type IndexedVerificationFailure struct {
Index int `json:"index"`
Message string `json:"message"`
}
// WriteStateFetchError writes an appropriate error based on the supplied argument.
// The argument error should be a result of fetching state.
func WriteStateFetchError(w http.ResponseWriter, err error) {
if stateNotFoundErr, ok := err.(*lookup.StateNotFoundError); ok {
http2.HandleError(w, "Could not get state: "+stateNotFoundErr.Error(), http.StatusNotFound)
}
if parseErr, ok := err.(*lookup.StateIdParseError); ok {
http2.HandleError(w, "Invalid state ID: "+parseErr.Error(), http.StatusBadRequest)
}
http2.HandleError(w, "Could not get state: "+err.Error(), http.StatusInternalServerError)
}
// WriteBlockFetchError writes an appropriate error based on the supplied argument.
// The argument error should be a result of fetching block.
func WriteBlockFetchError(w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock, err error) bool {
if invalidBlockIdErr, ok := err.(*lookup.BlockIdParseError); ok {
http2.HandleError(w, "Invalid block ID: "+invalidBlockIdErr.Error(), http.StatusBadRequest)
return false
}
if err != nil {
http2.HandleError(w, "Could not get block from block ID: %s"+err.Error(), http.StatusInternalServerError)
return false
}
if err = blocks.BeaconBlockIsNil(blk); err != nil {
http2.HandleError(w, "Could not find requested block: %s"+err.Error(), http.StatusNotFound)
return false
}
return true
}

View File

@@ -311,6 +311,12 @@ type DepositData struct {
Signature string `json:"signature" validate:"required"`
}
type SignedBeaconBlockHeaderContainer struct {
Header *SignedBeaconBlockHeader `json:"header"`
Root string `json:"root"`
Canonical bool `json:"canonical"`
}
type SignedBeaconBlockHeader struct {
Message *BeaconBlockHeader `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`

View File

@@ -423,7 +423,7 @@ func (b *BeaconBlockBellatrix) ToConsensus() (*eth.BeaconBlockBellatrix, error)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas")
}
@@ -638,7 +638,7 @@ func (b *BlindedBeaconBlockBellatrix) ToConsensus() (*eth.BlindedBeaconBlockBell
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas")
}
@@ -845,7 +845,7 @@ func (b *BeaconBlockCapella) ToConsensus() (*eth.BeaconBlockCapella, error) {
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas")
}
@@ -1095,7 +1095,7 @@ func (b *BlindedBeaconBlockCapella) ToConsensus() (*eth.BlindedBeaconBlockCapell
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas")
}
@@ -1268,8 +1268,8 @@ func (b *SignedBlindedBeaconBlockContentsDeneb) ToGeneric() (*eth.GenericSignedB
return nil, NewDecodeError(err, "SignedBlindedBlock")
}
block := &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: signedBlindedBlock,
Blobs: signedBlindedBlobSidecars,
SignedBlindedBlock: signedBlindedBlock,
SignedBlindedBlobSidecars: signedBlindedBlobSidecars,
}
return &eth.GenericSignedBeaconBlock{Block: &eth.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: block}, IsBlinded: true, PayloadValue: 0 /* can't get payload value from blinded block */}, nil
}
@@ -1444,7 +1444,7 @@ func (b *BeaconBlockDeneb) ToConsensus() (*eth.BeaconBlockDeneb, error) {
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas")
}
@@ -1706,7 +1706,7 @@ func (b *SignedBlindedBeaconBlockDeneb) ToConsensus() (*eth.SignedBlindedBeaconB
return nil, err
}
return &eth.SignedBlindedBeaconBlockDeneb{
Block: blindedBlock,
Message: blindedBlock,
Signature: sig,
}, nil
}
@@ -1836,7 +1836,7 @@ func (b *BlindedBeaconBlockDeneb) ToConsensus() (*eth.BlindedBeaconBlockDeneb, e
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData")
}
payloadBaseFeePerGas, err := uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
payloadBaseFeePerGas, err := Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas)
if err != nil {
return nil, NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas")
}
@@ -1994,6 +1994,16 @@ func (s *BlindedBlobSidecar) ToConsensus() (*eth.BlindedBlobSidecar, error) {
return bsc, nil
}
func BeaconBlockHeaderFromConsensus(h *eth.BeaconBlockHeader) *BeaconBlockHeader {
return &BeaconBlockHeader{
Slot: strconv.FormatUint(uint64(h.Slot), 10),
ProposerIndex: strconv.FormatUint(uint64(h.ProposerIndex), 10),
ParentRoot: hexutil.Encode(h.ParentRoot),
StateRoot: hexutil.Encode(h.StateRoot),
BodyRoot: hexutil.Encode(h.BodyRoot),
}
}
func BeaconBlockFromConsensus(b *eth.BeaconBlock) (*BeaconBlock, error) {
proposerSlashings, err := ProposerSlashingsFromConsensus(b.Body.ProposerSlashings)
if err != nil {
@@ -2407,9 +2417,9 @@ func BlindedBeaconBlockContentsDenebFromConsensus(b *eth.BlindedBeaconBlockAndBl
func SignedBlindedBeaconBlockContentsDenebFromConsensus(b *eth.SignedBlindedBeaconBlockAndBlobsDeneb) (*SignedBlindedBeaconBlockContentsDeneb, error) {
var blindedBlobSidecars []*SignedBlindedBlobSidecar
if len(b.Blobs) != 0 {
blindedBlobSidecars = make([]*SignedBlindedBlobSidecar, len(b.Blobs))
for i, s := range b.Blobs {
if len(b.SignedBlindedBlobSidecars) != 0 {
blindedBlobSidecars = make([]*SignedBlindedBlobSidecar, len(b.SignedBlindedBlobSidecars))
for i, s := range b.SignedBlindedBlobSidecars {
signedBlob, err := SignedBlindedBlobSidecarFromConsensus(s)
if err != nil {
return nil, err
@@ -2417,7 +2427,7 @@ func SignedBlindedBeaconBlockContentsDenebFromConsensus(b *eth.SignedBlindedBeac
blindedBlobSidecars[i] = signedBlob
}
}
blindedBlock, err := SignedBlindedBeaconBlockDenebFromConsensus(b.Block)
blindedBlock, err := SignedBlindedBeaconBlockDenebFromConsensus(b.SignedBlindedBlock)
if err != nil {
return nil, err
}
@@ -2554,7 +2564,7 @@ func BlindedBeaconBlockDenebFromConsensus(b *eth.BlindedBeaconBlockDeneb) (*Blin
}
func SignedBlindedBeaconBlockDenebFromConsensus(b *eth.SignedBlindedBeaconBlockDeneb) (*SignedBlindedBeaconBlockDeneb, error) {
block, err := BlindedBeaconBlockDenebFromConsensus(b.Block)
block, err := BlindedBeaconBlockDenebFromConsensus(b.Message)
if err != nil {
return nil, err
}
@@ -3168,7 +3178,7 @@ func BlsChangesFromConsensus(src []*eth.SignedBLSToExecutionChange) ([]*SignedBl
return changes, nil
}
func uint256ToSSZBytes(num string) ([]byte, error) {
func Uint256ToSSZBytes(num string) ([]byte, error) {
uint256, ok := new(big.Int).SetString(num, 10)
if !ok {
return nil, errors.New("could not parse Uint256")

View File

@@ -18,6 +18,7 @@ go_library(
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/kv:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",

View File

@@ -19,6 +19,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/builder"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/core"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
@@ -651,8 +652,8 @@ func (s *Server) GetAttesterDuties(w http.ResponseWriter, r *http.Request) {
return
}
requestedEpoch := primitives.Epoch(requestedEpochUint)
var req GetAttesterDutiesRequest
err := json.NewDecoder(r.Body).Decode(&req.ValidatorIndices)
var indices []string
err := json.NewDecoder(r.Body).Decode(&indices)
switch {
case err == io.EOF:
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
@@ -661,12 +662,12 @@ func (s *Server) GetAttesterDuties(w http.ResponseWriter, r *http.Request) {
http2.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if len(req.ValidatorIndices) == 0 {
if len(indices) == 0 {
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
return
}
requestedValIndices := make([]primitives.ValidatorIndex, len(req.ValidatorIndices))
for i, ix := range req.ValidatorIndices {
requestedValIndices := make([]primitives.ValidatorIndex, len(indices))
for i, ix := range indices {
valIx, valid := shared.ValidateUint(w, fmt.Sprintf("ValidatorIndices[%d]", i), ix)
if !valid {
return
@@ -804,10 +805,33 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
http2.HandleError(w, fmt.Sprintf("Could not get start slot of epoch %d: %v", requestedEpoch, err), http.StatusInternalServerError)
return
}
st, err := s.Stater.StateBySlot(ctx, epochStartSlot)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not get state for slot %d: %v ", epochStartSlot, err), http.StatusInternalServerError)
return
var st state.BeaconState
// if the requested epoch is new, use the head state and the next slot cache
if requestedEpoch < currentEpoch {
st, err = s.Stater.StateBySlot(ctx, epochStartSlot)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not get state for slot %d: %v ", epochStartSlot, err), http.StatusInternalServerError)
return
}
} else {
st, err = s.HeadFetcher.HeadState(ctx)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not get head state: %v ", err), http.StatusInternalServerError)
return
}
// Advance state with empty transitions up to the requested epoch start slot.
if st.Slot() < epochStartSlot {
headRoot, err := s.HeadFetcher.HeadRoot(ctx)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not get head root: %v ", err), http.StatusInternalServerError)
return
}
st, err = transition.ProcessSlotsUsingNextSlotCache(ctx, st, headRoot, epochStartSlot)
if err != nil {
http2.HandleError(w, fmt.Sprintf("Could not process slots up to %d: %v ", epochStartSlot, err), http.StatusInternalServerError)
return
}
}
}
var proposals map[primitives.ValidatorIndex][]primitives.Slot
@@ -831,7 +855,6 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
pubkey48 := val.PublicKey()
pubkey := pubkey48[:]
for _, slot := range proposalSlots {
s.ProposerSlotIndexCache.SetProposerAndPayloadIDs(slot, index, [8]byte{} /* payloadID */, [32]byte{} /* head root */)
duties = append(duties, &ProposerDuty{
Pubkey: hexutil.Encode(pubkey),
ValidatorIndex: strconv.FormatUint(uint64(index), 10),
@@ -839,11 +862,6 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
})
}
}
sort.Slice(duties, func(i, j int) bool {
return duties[i].Slot < duties[j].Slot
})
s.ProposerSlotIndexCache.PrunePayloadIDs(epochStartSlot)
dependentRoot, err := proposalDependentRoot(st, requestedEpoch)
if err != nil {
@@ -855,6 +873,9 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
http2.HandleError(w, "Could not check optimistic status: "+err.Error(), http.StatusInternalServerError)
return
}
if !sortProposerDuties(w, duties) {
return
}
resp := &GetProposerDutiesResponse{
DependentRoot: hexutil.Encode(dependentRoot),
@@ -893,8 +914,8 @@ func (s *Server) GetSyncCommitteeDuties(w http.ResponseWriter, r *http.Request)
http2.HandleError(w, "Sync committees are not supported for Phase0", http.StatusBadRequest)
return
}
var req GetSyncCommitteeDutiesRequest
err := json.NewDecoder(r.Body).Decode(&req.ValidatorIndices)
var indices []string
err := json.NewDecoder(r.Body).Decode(&indices)
switch {
case err == io.EOF:
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
@@ -903,12 +924,12 @@ func (s *Server) GetSyncCommitteeDuties(w http.ResponseWriter, r *http.Request)
http2.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if len(req.ValidatorIndices) == 0 {
if len(indices) == 0 {
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
return
}
requestedValIndices := make([]primitives.ValidatorIndex, len(req.ValidatorIndices))
for i, ix := range req.ValidatorIndices {
requestedValIndices := make([]primitives.ValidatorIndex, len(indices))
for i, ix := range indices {
valIx, valid := shared.ValidateUint(w, fmt.Sprintf("ValidatorIndices[%d]", i), ix)
if !valid {
return
@@ -982,6 +1003,112 @@ func (s *Server) GetSyncCommitteeDuties(w http.ResponseWriter, r *http.Request)
http2.WriteJson(w, resp)
}
// GetLiveness requests the beacon node to indicate if a validator has been observed to be live in a given epoch.
// The beacon node might detect liveness by observing messages from the validator on the network,
// in the beacon chain, from its API or from any other source.
// A beacon node SHOULD support the current and previous epoch, however it MAY support earlier epoch.
// It is important to note that the values returned by the beacon node are not canonical;
// they are best-effort and based upon a subjective view of the network.
// A beacon node that was recently started or suffered a network partition may indicate that a validator is not live when it actually is.
func (s *Server) GetLiveness(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.GetLiveness")
defer span.End()
rawEpoch := mux.Vars(r)["epoch"]
requestedEpochUint, valid := shared.ValidateUint(w, "Epoch", rawEpoch)
if !valid {
return
}
requestedEpoch := primitives.Epoch(requestedEpochUint)
var indices []string
err := json.NewDecoder(r.Body).Decode(&indices)
switch {
case err == io.EOF:
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
http2.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if len(indices) == 0 {
http2.HandleError(w, "No data submitted", http.StatusBadRequest)
return
}
requestedValIndices := make([]primitives.ValidatorIndex, len(indices))
for i, ix := range indices {
valIx, valid := shared.ValidateUint(w, fmt.Sprintf("ValidatorIndices[%d]", i), ix)
if !valid {
return
}
requestedValIndices[i] = primitives.ValidatorIndex(valIx)
}
// First we check if the requested epoch is the current epoch.
// If it is, then we won't be able to fetch the state at the end of the epoch.
// In that case we get participation info from the head state.
// We can also use the head state to get participation info for the previous epoch.
headSt, err := s.HeadFetcher.HeadState(ctx)
if err != nil {
http2.HandleError(w, "Could not get head state: "+err.Error(), http.StatusInternalServerError)
return
}
currEpoch := slots.ToEpoch(headSt.Slot())
if requestedEpoch > currEpoch {
http2.HandleError(w, "Requested epoch cannot be in the future", http.StatusBadRequest)
return
}
var st state.BeaconState
var participation []byte
if requestedEpoch == currEpoch {
st = headSt
participation, err = st.CurrentEpochParticipation()
if err != nil {
http2.HandleError(w, "Could not get current epoch participation: "+err.Error(), http.StatusInternalServerError)
return
}
} else if requestedEpoch == currEpoch-1 {
st = headSt
participation, err = st.PreviousEpochParticipation()
if err != nil {
http2.HandleError(w, "Could not get previous epoch participation: "+err.Error(), http.StatusInternalServerError)
return
}
} else {
epochEnd, err := slots.EpochEnd(requestedEpoch)
if err != nil {
http2.HandleError(w, "Could not get requested epoch's end slot: "+err.Error(), http.StatusInternalServerError)
return
}
st, err = s.Stater.StateBySlot(ctx, epochEnd)
if err != nil {
http2.HandleError(w, "Could not get slot for requested epoch: "+err.Error(), http.StatusInternalServerError)
return
}
participation, err = st.CurrentEpochParticipation()
if err != nil {
http2.HandleError(w, "Could not get current epoch participation: "+err.Error(), http.StatusInternalServerError)
return
}
}
resp := &GetLivenessResponse{
Data: make([]*ValidatorLiveness, len(requestedValIndices)),
}
for i, vi := range requestedValIndices {
if vi >= primitives.ValidatorIndex(len(participation)) {
http2.HandleError(w, fmt.Sprintf("Validator index %d is invalid", vi), http.StatusBadRequest)
return
}
resp.Data[i] = &ValidatorLiveness{
Index: strconv.FormatUint(uint64(vi), 10),
IsLive: participation[vi] != 0,
}
}
http2.WriteJson(w, resp)
}
// attestationDependentRoot is get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)
// or the genesis block root in the case of underflow.
func attestationDependentRoot(s state.BeaconState, epoch primitives.Epoch) ([]byte, error) {
@@ -1053,3 +1180,23 @@ func syncCommitteeDuties(
}
return duties, nil
}
func sortProposerDuties(w http.ResponseWriter, duties []*ProposerDuty) bool {
ok := true
sort.Slice(duties, func(i, j int) bool {
si, err := strconv.ParseUint(duties[i].Slot, 10, 64)
if err != nil {
http2.HandleError(w, "Could not parse slot: "+err.Error(), http.StatusInternalServerError)
ok = false
return false
}
sj, err := strconv.ParseUint(duties[j].Slot, 10, 64)
if err != nil {
http2.HandleError(w, "Could not parse slot: "+err.Error(), http.StatusInternalServerError)
ok = false
return false
}
return si < sj
})
return ok
}

View File

@@ -1856,9 +1856,6 @@ func TestGetProposerDuties(t *testing.T) {
expectedDuty = duty
}
}
vid, _, has := s.ProposerSlotIndexCache.GetProposerPayloadIDs(11, [32]byte{})
require.Equal(t, true, has)
require.Equal(t, primitives.ValidatorIndex(12289), vid)
require.NotNil(t, expectedDuty, "Expected duty for slot 11 not found")
assert.Equal(t, "12289", expectedDuty.ValidatorIndex)
assert.Equal(t, hexutil.Encode(pubKeys[12289]), expectedDuty.Pubkey)
@@ -1898,52 +1895,10 @@ func TestGetProposerDuties(t *testing.T) {
expectedDuty = duty
}
}
vid, _, has := s.ProposerSlotIndexCache.GetProposerPayloadIDs(43, [32]byte{})
require.Equal(t, true, has)
require.Equal(t, primitives.ValidatorIndex(1360), vid)
require.NotNil(t, expectedDuty, "Expected duty for slot 43 not found")
assert.Equal(t, "1360", expectedDuty.ValidatorIndex)
assert.Equal(t, hexutil.Encode(pubKeys[1360]), expectedDuty.Pubkey)
})
t.Run("prune payload ID cache", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
require.NoError(t, bs.SetSlot(params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, bs.SetBlockRoots(roots))
chainSlot := params.BeaconConfig().SlotsPerEpoch
chain := &mockChain.ChainService{
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
s := &Server{
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{params.BeaconConfig().SlotsPerEpoch: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
SyncChecker: &mockSync.Sync{IsSyncing: false},
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
}
s.ProposerSlotIndexCache.SetProposerAndPayloadIDs(1, 1, [8]byte{1}, [32]byte{2})
s.ProposerSlotIndexCache.SetProposerAndPayloadIDs(31, 2, [8]byte{2}, [32]byte{3})
s.ProposerSlotIndexCache.SetProposerAndPayloadIDs(32, 4309, [8]byte{3}, [32]byte{4})
request := httptest.NewRequest(http.MethodGet, "http://www.example.com/eth/v1/validator/duties/proposer/{epoch}", nil)
request = mux.SetURLVars(request, map[string]string{"epoch": "1"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetProposerDuties(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
vid, _, has := s.ProposerSlotIndexCache.GetProposerPayloadIDs(1, [32]byte{})
require.Equal(t, false, has)
require.Equal(t, primitives.ValidatorIndex(0), vid)
vid, _, has = s.ProposerSlotIndexCache.GetProposerPayloadIDs(2, [32]byte{})
require.Equal(t, false, has)
require.Equal(t, primitives.ValidatorIndex(0), vid)
vid, _, has = s.ProposerSlotIndexCache.GetProposerPayloadIDs(32, [32]byte{})
require.Equal(t, true, has)
require.Equal(t, primitives.ValidatorIndex(10565), vid)
})
t.Run("epoch out of bounds", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
@@ -2567,6 +2522,185 @@ func BenchmarkServer_PrepareBeaconProposer(b *testing.B) {
}
}
func TestGetLiveness(t *testing.T) {
// Setup:
// Epoch 0 - both validators not live
// Epoch 1 - validator with index 1 is live
// Epoch 2 - validator with index 0 is live
oldSt, err := util.NewBeaconStateBellatrix()
require.NoError(t, err)
require.NoError(t, oldSt.AppendCurrentParticipationBits(0))
require.NoError(t, oldSt.AppendCurrentParticipationBits(0))
headSt, err := util.NewBeaconStateBellatrix()
require.NoError(t, err)
require.NoError(t, headSt.SetSlot(params.BeaconConfig().SlotsPerEpoch*2))
require.NoError(t, headSt.AppendPreviousParticipationBits(0))
require.NoError(t, headSt.AppendPreviousParticipationBits(1))
require.NoError(t, headSt.AppendCurrentParticipationBits(1))
require.NoError(t, headSt.AppendCurrentParticipationBits(0))
s := &Server{
HeadFetcher: &mockChain.ChainService{State: headSt},
Stater: &testutil.MockStater{
// We configure states for last slots of an epoch
StatesBySlot: map[primitives.Slot]state.BeaconState{
params.BeaconConfig().SlotsPerEpoch - 1: oldSt,
params.BeaconConfig().SlotsPerEpoch*3 - 1: headSt,
},
},
}
t.Run("old epoch", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "0"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetLivenessResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.NotNil(t, resp.Data)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == "0" && !data0.IsLive) || (data0.Index == "1" && !data0.IsLive))
assert.Equal(t, true, (data1.Index == "0" && !data1.IsLive) || (data1.Index == "1" && !data1.IsLive))
})
t.Run("previous epoch", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "1"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetLivenessResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.NotNil(t, resp.Data)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == "0" && !data0.IsLive) || (data0.Index == "1" && data0.IsLive))
assert.Equal(t, true, (data1.Index == "0" && !data1.IsLive) || (data1.Index == "1" && data1.IsLive))
})
t.Run("current epoch", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "2"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &GetLivenessResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
require.NotNil(t, resp.Data)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == "0" && data0.IsLive) || (data0.Index == "1" && !data0.IsLive))
assert.Equal(t, true, (data1.Index == "0" && data1.IsLive) || (data1.Index == "1" && !data1.IsLive))
})
t.Run("future epoch", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "3"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
require.StringContains(t, "Requested epoch cannot be in the future", e.Message)
})
t.Run("no epoch provided", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.Equal(t, true, strings.Contains(e.Message, "Epoch is required"))
})
t.Run("invalid epoch provided", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "foo"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.Equal(t, true, strings.Contains(e.Message, "Epoch is invalid"))
})
t.Run("no body", func(t *testing.T) {
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", nil)
request = mux.SetURLVars(request, map[string]string{"epoch": "3"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "No data submitted", e.Message)
})
t.Run("empty", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "3"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.StringContains(t, "No data submitted", e.Message)
})
t.Run("unknown validator index", func(t *testing.T) {
var body bytes.Buffer
_, err := body.WriteString("[\"0\",\"1\",\"2\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/validator/liveness/{epoch}", &body)
request = mux.SetURLVars(request, map[string]string{"epoch": "0"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLiveness(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &http2.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
require.StringContains(t, "Validator index 2 is invalid", e.Message)
})
}
var (
singleContribution = `[
{

View File

@@ -34,10 +34,6 @@ type ProduceSyncCommitteeContributionResponse struct {
Data *shared.SyncCommitteeContribution `json:"data"`
}
type GetAttesterDutiesRequest struct {
ValidatorIndices []string `json:"validator_indices"`
}
type GetAttesterDutiesResponse struct {
DependentRoot string `json:"dependent_root"`
ExecutionOptimistic bool `json:"execution_optimistic"`
@@ -66,10 +62,6 @@ type ProposerDuty struct {
Slot string `json:"slot"`
}
type GetSyncCommitteeDutiesRequest struct {
ValidatorIndices []string `json:"validator_indices"`
}
type GetSyncCommitteeDutiesResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Data []*SyncCommitteeDuty `json:"data"`
@@ -88,3 +80,12 @@ type ProduceBlockV3Response struct {
ExecutionPayloadValue string `json:"execution_payload_value"`
Data json.RawMessage `json:"data"` // represents the block values based on the version
}
type GetLivenessResponse struct {
Data []*ValidatorLiveness `json:"data"`
}
type ValidatorLiveness struct {
Index string `json:"index"`
IsLive bool `json:"is_live"`
}

View File

@@ -5,20 +5,15 @@ import (
"fmt"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"go.opencensus.io/trace"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
var errParticipation = status.Error(codes.Internal, "Could not obtain epoch participation")
// ProduceBlockV2 requests the beacon node to produce a valid unsigned beacon block, which can then be signed by a proposer and submitted.
// By definition `/eth/v2/validator/blocks/{slot}`, does not produce block using mev-boost and relayer network.
// The following endpoint states that the returned object is a BeaconBlock, not a BlindedBeaconBlock. As such, the block must return a full ExecutionPayload:
@@ -512,73 +507,3 @@ func (vs *Server) ProduceBlindedBlockSSZ(ctx context.Context, req *ethpbv1.Produ
}
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}
// GetLiveness requests the beacon node to indicate if a validator has been observed to be live in a given epoch.
// The beacon node might detect liveness by observing messages from the validator on the network,
// in the beacon chain, from its API or from any other source.
// A beacon node SHOULD support the current and previous epoch, however it MAY support earlier epoch.
// It is important to note that the values returned by the beacon node are not canonical;
// they are best-effort and based upon a subjective view of the network.
// A beacon node that was recently started or suffered a network partition may indicate that a validator is not live when it actually is.
func (vs *Server) GetLiveness(ctx context.Context, req *ethpbv2.GetLivenessRequest) (*ethpbv2.GetLivenessResponse, error) {
ctx, span := trace.StartSpan(ctx, "validator.GetLiveness")
defer span.End()
var participation []byte
// First we check if the requested epoch is the current epoch.
// If it is, then we won't be able to fetch the state at the end of the epoch.
// In that case we get participation info from the head state.
// We can also use the head state to get participation info for the previous epoch.
headSt, err := vs.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get head state")
}
currEpoch := slots.ToEpoch(headSt.Slot())
if req.Epoch > currEpoch {
return nil, status.Error(codes.InvalidArgument, "Requested epoch cannot be in the future")
}
var st state.BeaconState
if req.Epoch == currEpoch {
st = headSt
participation, err = st.CurrentEpochParticipation()
if err != nil {
return nil, errParticipation
}
} else if req.Epoch == currEpoch-1 {
st = headSt
participation, err = st.PreviousEpochParticipation()
if err != nil {
return nil, errParticipation
}
} else {
epochEnd, err := slots.EpochEnd(req.Epoch)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get requested epoch's end slot")
}
st, err = vs.Stater.StateBySlot(ctx, epochEnd)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get slot for requested epoch")
}
participation, err = st.CurrentEpochParticipation()
if err != nil {
return nil, errParticipation
}
}
resp := &ethpbv2.GetLivenessResponse{
Data: make([]*ethpbv2.GetLivenessResponse_Liveness, len(req.Index)),
}
for i, vi := range req.Index {
if vi >= primitives.ValidatorIndex(len(participation)) {
return nil, status.Errorf(codes.InvalidArgument, "Validator index %d is invalid", vi)
}
resp.Data[i] = &ethpbv2.GetLivenessResponse_Liveness{
Index: vi,
IsLive: participation[vi] != 0,
}
}
return resp, nil
}

View File

@@ -7,11 +7,8 @@ import (
"github.com/golang/mock/gomock"
mockChain "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
builderTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/builder/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
@@ -345,7 +342,7 @@ func TestProduceBlockV2SSZ(t *testing.T) {
genericBlock := &ethpbalpha.GenericBeaconBlock{
Block: &ethpbalpha.GenericBeaconBlock_BlindedDeneb{
BlindedDeneb: &ethpbalpha.BlindedBeaconBlockAndBlobsDeneb{
Block: blk.Block,
Block: blk.Message,
Blobs: blobs,
},
},
@@ -508,7 +505,7 @@ func TestProduceBlindedBlock(t *testing.T) {
genericBlock := &ethpbalpha.GenericBeaconBlock{
Block: &ethpbalpha.GenericBeaconBlock_BlindedDeneb{
BlindedDeneb: &ethpbalpha.BlindedBeaconBlockAndBlobsDeneb{
Block: blk.Block,
Block: blk.Message,
Blobs: blobs,
},
},
@@ -718,7 +715,7 @@ func TestProduceBlindedBlockSSZ(t *testing.T) {
genericBlock := &ethpbalpha.GenericBeaconBlock{
Block: &ethpbalpha.GenericBeaconBlock_BlindedDeneb{
BlindedDeneb: &ethpbalpha.BlindedBeaconBlockAndBlobsDeneb{
Block: blk.Block,
Block: blk.Message,
Blobs: blobs,
},
},
@@ -806,82 +803,3 @@ func TestProduceBlindedBlockSSZ(t *testing.T) {
require.ErrorContains(t, "Syncing to latest head", err)
})
}
func TestGetLiveness(t *testing.T) {
ctx := context.Background()
// Setup:
// Epoch 0 - both validators not live
// Epoch 1 - validator with index 1 is live
// Epoch 2 - validator with index 0 is live
oldSt, err := util.NewBeaconStateBellatrix()
require.NoError(t, err)
require.NoError(t, oldSt.AppendCurrentParticipationBits(0))
require.NoError(t, oldSt.AppendCurrentParticipationBits(0))
headSt, err := util.NewBeaconStateBellatrix()
require.NoError(t, err)
require.NoError(t, headSt.SetSlot(params.BeaconConfig().SlotsPerEpoch*2))
require.NoError(t, headSt.AppendPreviousParticipationBits(0))
require.NoError(t, headSt.AppendPreviousParticipationBits(1))
require.NoError(t, headSt.AppendCurrentParticipationBits(1))
require.NoError(t, headSt.AppendCurrentParticipationBits(0))
server := &Server{
HeadFetcher: &mockChain.ChainService{State: headSt},
Stater: &testutil.MockStater{
// We configure states for last slots of an epoch
StatesBySlot: map[primitives.Slot]state.BeaconState{
params.BeaconConfig().SlotsPerEpoch - 1: oldSt,
params.BeaconConfig().SlotsPerEpoch*3 - 1: headSt,
},
},
}
t.Run("old epoch", func(t *testing.T) {
resp, err := server.GetLiveness(ctx, &ethpbv2.GetLivenessRequest{
Epoch: 0,
Index: []primitives.ValidatorIndex{0, 1},
})
require.NoError(t, err)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == 0 && !data0.IsLive) || (data0.Index == 1 && !data0.IsLive))
assert.Equal(t, true, (data1.Index == 0 && !data1.IsLive) || (data1.Index == 1 && !data1.IsLive))
})
t.Run("previous epoch", func(t *testing.T) {
resp, err := server.GetLiveness(ctx, &ethpbv2.GetLivenessRequest{
Epoch: 1,
Index: []primitives.ValidatorIndex{0, 1},
})
require.NoError(t, err)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == 0 && !data0.IsLive) || (data0.Index == 1 && data0.IsLive))
assert.Equal(t, true, (data1.Index == 0 && !data1.IsLive) || (data1.Index == 1 && data1.IsLive))
})
t.Run("current epoch", func(t *testing.T) {
resp, err := server.GetLiveness(ctx, &ethpbv2.GetLivenessRequest{
Epoch: 2,
Index: []primitives.ValidatorIndex{0, 1},
})
require.NoError(t, err)
data0 := resp.Data[0]
data1 := resp.Data[1]
assert.Equal(t, true, (data0.Index == 0 && data0.IsLive) || (data0.Index == 1 && !data0.IsLive))
assert.Equal(t, true, (data1.Index == 0 && data1.IsLive) || (data1.Index == 1 && !data1.IsLive))
})
t.Run("future epoch", func(t *testing.T) {
_, err := server.GetLiveness(ctx, &ethpbv2.GetLivenessRequest{
Epoch: 3,
Index: []primitives.ValidatorIndex{0, 1},
})
require.ErrorContains(t, "Requested epoch cannot be in the future", err)
})
t.Run("unknown validator index", func(t *testing.T) {
_, err := server.GetLiveness(ctx, &ethpbv2.GetLivenessRequest{
Epoch: 0,
Index: []primitives.ValidatorIndex{0, 1, 2},
})
require.ErrorContains(t, "Validator index 2 is invalid", err)
})
}

View File

@@ -315,7 +315,7 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign
var blindSidecars []*ethpb.SignedBlindedBlobSidecar
if blk.Version() >= version.Deneb && blk.IsBlinded() {
blindSidecars = req.GetBlindedDeneb().Blobs
blindSidecars = req.GetBlindedDeneb().SignedBlindedBlobSidecars
}
unblinder, err := newUnblinder(blk, blindSidecars, vs.BlockBuilder)

View File

@@ -750,17 +750,17 @@ func TestProposer_ProposeBlock_OK(t *testing.T) {
name: "blind capella",
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
blockToPropose := util.NewBlindedBeaconBlockDeneb()
blockToPropose.Block.Slot = 5
blockToPropose.Block.ParentRoot = parent[:]
blockToPropose.Message.Slot = 5
blockToPropose.Message.ParentRoot = parent[:]
txRoot, err := ssz.TransactionsRoot([][]byte{})
require.NoError(t, err)
withdrawalsRoot, err := ssz.WithdrawalSliceRoot([]*enginev1.Withdrawal{}, fieldparams.MaxWithdrawalsPerPayload)
require.NoError(t, err)
blockToPropose.Block.Body.ExecutionPayloadHeader.TransactionsRoot = txRoot[:]
blockToPropose.Block.Body.ExecutionPayloadHeader.WithdrawalsRoot = withdrawalsRoot[:]
blockToPropose.Message.Body.ExecutionPayloadHeader.TransactionsRoot = txRoot[:]
blockToPropose.Message.Body.ExecutionPayloadHeader.WithdrawalsRoot = withdrawalsRoot[:]
blk := &ethpb.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: &ethpb.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: blockToPropose,
Blobs: []*ethpb.SignedBlindedBlobSidecar{
SignedBlindedBlock: blockToPropose,
SignedBlindedBlobSidecars: []*ethpb.SignedBlindedBlobSidecar{
{
Message: &ethpb.BlindedBlobSidecar{
BlockRoot: []byte{0x01},

View File

@@ -31,6 +31,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/network/forks"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
@@ -138,12 +139,26 @@ func (vs *Server) ValidatorIndex(ctx context.Context, req *ethpb.ValidatorIndexR
}
// DomainData fetches the current domain version information from the beacon state.
func (vs *Server) DomainData(_ context.Context, request *ethpb.DomainRequest) (*ethpb.DomainResponse, error) {
func (vs *Server) DomainData(ctx context.Context, request *ethpb.DomainRequest) (*ethpb.DomainResponse, error) {
fork, err := forks.Fork(request.Epoch)
if err != nil {
return nil, err
}
headGenesisValidatorsRoot := vs.HeadFetcher.HeadGenesisValidatorsRoot()
isExitDomain := [4]byte(request.Domain) == params.BeaconConfig().DomainVoluntaryExit
if isExitDomain {
hs, err := vs.HeadFetcher.HeadStateReadOnly(ctx)
if err != nil {
return nil, err
}
if hs.Version() >= version.Deneb {
fork = &ethpb.Fork{
PreviousVersion: params.BeaconConfig().CapellaForkVersion,
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
}
}
}
dv, err := signing.Domain(fork, request.Epoch, bytesutil.ToBytes4(request.Domain), headGenesisValidatorsRoot[:])
if err != nil {
return nil, err

View File

@@ -10,10 +10,12 @@ import (
"github.com/prysmaticlabs/prysm/v4/async/event"
mockChain "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
mockExecution "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
@@ -309,3 +311,56 @@ func TestWaitForChainStart_NotStartedThenLogFired(t *testing.T) {
exitRoutine <- true
require.LogsContain(t, hook, "Sending genesis time")
}
func TestServer_DomainData_Exits(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
cfg.ForkVersionSchedule = map[[4]byte]primitives.Epoch{
[4]byte(cfg.GenesisForkVersion): primitives.Epoch(0),
[4]byte(cfg.AltairForkVersion): primitives.Epoch(5),
[4]byte(cfg.BellatrixForkVersion): primitives.Epoch(10),
[4]byte(cfg.CapellaForkVersion): primitives.Epoch(15),
[4]byte(cfg.DenebForkVersion): primitives.Epoch(20),
}
params.OverrideBeaconConfig(cfg)
beaconState := &ethpb.BeaconStateBellatrix{
Slot: 4000,
}
block := util.NewBeaconBlock()
genesisRoot, err := block.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
s, err := state_native.InitializeFromProtoUnsafeBellatrix(beaconState)
require.NoError(t, err)
vs := &Server{
Ctx: context.Background(),
ChainStartFetcher: &mockExecution.Chain{},
HeadFetcher: &mockChain.ChainService{State: s, Root: genesisRoot[:]},
}
reqDomain, err := vs.DomainData(context.Background(), &ethpb.DomainRequest{
Epoch: 100,
Domain: params.BeaconConfig().DomainDeposit[:],
})
assert.NoError(t, err)
wantedDomain, err := signing.ComputeDomain(params.BeaconConfig().DomainDeposit, params.BeaconConfig().DenebForkVersion, make([]byte, 32))
assert.NoError(t, err)
assert.DeepEqual(t, reqDomain.SignatureDomain, wantedDomain)
beaconStateNew := &ethpb.BeaconStateDeneb{
Slot: 4000,
}
s, err = state_native.InitializeFromProtoUnsafeDeneb(beaconStateNew)
require.NoError(t, err)
vs.HeadFetcher = &mockChain.ChainService{State: s, Root: genesisRoot[:]}
reqDomain, err = vs.DomainData(context.Background(), &ethpb.DomainRequest{
Epoch: 100,
Domain: params.BeaconConfig().DomainVoluntaryExit[:],
})
require.NoError(t, err)
wantedDomain, err = signing.ComputeDomain(params.BeaconConfig().DomainVoluntaryExit, params.BeaconConfig().CapellaForkVersion, make([]byte, 32))
require.NoError(t, err)
assert.DeepEqual(t, reqDomain.SignatureDomain, wantedDomain)
}

View File

@@ -158,6 +158,10 @@ func copyBlockData(src interfaces.SignedBeaconBlock, dst interfaces.SignedBeacon
if err != nil && !errors.Is(err, consensus_types.ErrUnsupportedField) {
return errors.Wrap(err, "could not get bls to execution changes")
}
kzgCommitments, err := src.Block().Body().BlobKzgCommitments()
if err != nil && !errors.Is(err, consensus_types.ErrUnsupportedField) {
return errors.Wrap(err, "could not get blob kzg commitments")
}
dst.SetSlot(src.Block().Slot())
dst.SetProposerIndex(src.Block().ProposerIndex())
@@ -178,6 +182,9 @@ func copyBlockData(src interfaces.SignedBeaconBlock, dst interfaces.SignedBeacon
if err = dst.SetBLSToExecutionChanges(blsToExecChanges); err != nil && !errors.Is(err, consensus_types.ErrUnsupportedField) {
return errors.Wrap(err, "could not set bls to execution changes")
}
if err = dst.SetBlobKzgCommitments(kzgCommitments); err != nil && !errors.Is(err, consensus_types.ErrUnsupportedField) {
return errors.Wrap(err, "could not set bls to execution changes")
}
return nil
}
@@ -198,7 +205,7 @@ func (u *unblinder) blindedProtoBlock() (proto.Message, error) {
}, nil
case version.Deneb:
return &ethpb.SignedBlindedBeaconBlockDeneb{
Block: &ethpb.BlindedBeaconBlockDeneb{
Message: &ethpb.BlindedBeaconBlockDeneb{
Body: &ethpb.BlindedBeaconBlockBodyDeneb{},
},
}, nil

View File

@@ -276,9 +276,9 @@ func Test_unblindBuilderBlock(t *testing.T) {
}(),
blk: func() interfaces.SignedBeaconBlock {
b := util.NewBlindedBeaconBlockDeneb()
b.Block.Slot = 1
b.Block.ProposerIndex = 2
b.Block.Body.BlsToExecutionChanges = []*eth.SignedBLSToExecutionChange{
b.Message.Slot = 1
b.Message.ProposerIndex = 2
b.Message.Body.BlsToExecutionChanges = []*eth.SignedBLSToExecutionChange{
{
Message: &eth.BLSToExecutionChange{
ValidatorIndex: 123,
@@ -296,11 +296,12 @@ func Test_unblindBuilderBlock(t *testing.T) {
Signature: []byte("sig456"),
},
}
b.Message.Body.BlobKzgCommitments = [][]byte{{'c', 0}, {'c', 1}, {'c', 2}, {'c', 3}, {'c', 4}, {'c', 5}}
txRoot, err := ssz.TransactionsRoot([][]byte{})
require.NoError(t, err)
withdrawalsRoot, err := ssz.WithdrawalSliceRoot([]*v1.Withdrawal{}, fieldparams.MaxWithdrawalsPerPayload)
require.NoError(t, err)
b.Block.Body.ExecutionPayloadHeader = &v1.ExecutionPayloadHeaderDeneb{
b.Message.Body.ExecutionPayloadHeader = &v1.ExecutionPayloadHeaderDeneb{
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
StateRoot: make([]byte, fieldparams.RootLength),
@@ -350,6 +351,7 @@ func Test_unblindBuilderBlock(t *testing.T) {
Signature: []byte("sig456"),
},
}
b.Block.Body.BlobKzgCommitments = [][]byte{{'c', 0}, {'c', 1}, {'c', 2}, {'c', 3}, {'c', 4}, {'c', 5}}
b.Block.Body.ExecutionPayload = pDeneb
wb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)

View File

@@ -14,6 +14,7 @@ go_library(
"//beacon-chain/db:go_default_library",
"//beacon-chain/rpc/core:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/sync:go_default_library",

View File

@@ -7,10 +7,9 @@ import (
"strconv"
"strings"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/gorilla/mux"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
statenative "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
@@ -78,19 +77,7 @@ func (vs *Server) GetValidatorCount(w http.ResponseWriter, r *http.Request) {
st, err := vs.Stater.State(ctx, []byte(stateID))
if err != nil {
var errJson *http2.DefaultErrorJson
if _, ok := err.(*lookup.StateIdParseError); ok {
errJson = &http2.DefaultErrorJson{
Message: "invalid state ID",
Code: http.StatusBadRequest,
}
} else {
errJson = &http2.DefaultErrorJson{
Message: helpers.PrepareStateFetchError(err).Error(),
Code: http.StatusInternalServerError,
}
}
http2.WriteError(w, errJson)
shared.WriteStateFetchError(w, err)
return
}

View File

@@ -71,7 +71,7 @@ func TestGetValidatorCountInvalidRequest(t *testing.T) {
name: "invalid state ID",
stater: &testutil.MockStater{StateProviderFunc: stateIdCheckerStateFunc},
stateID: "helloworld",
expectedErrorMessage: "invalid state ID",
expectedErrorMessage: "Invalid state ID",
statusCode: http.StatusBadRequest,
},
}

View File

@@ -318,6 +318,7 @@ func (s *Service) Start() {
s.cfg.Router.HandleFunc("/eth/v1/validator/duties/proposer/{epoch}", validatorServerV1.GetProposerDuties).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/validator/duties/sync/{epoch}", validatorServerV1.GetSyncCommitteeDuties).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v1/validator/prepare_beacon_proposer", validatorServerV1.PrepareBeaconProposer).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v1/validator/liveness/{epoch}", validatorServerV1.GetLiveness).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v3/validator/blocks/{slot}", validatorServerV1.ProduceBlockV3).Methods(http.MethodGet)
@@ -439,7 +440,14 @@ func (s *Service) Start() {
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/voluntary_exits", beaconChainServerV1.ListVoluntaryExits).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/voluntary_exits", beaconChainServerV1.SubmitVoluntaryExit).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v1/beacon/pool/sync_committees", beaconChainServerV1.SubmitSyncCommitteeSignatures).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v1/beacon/headers", beaconChainServerV1.GetBlockHeaders).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/headers/{block_id}", beaconChainServerV1.GetBlockHeader).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/config/deposit_contract", beaconChainServerV1.GetDepositContract).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/genesis", beaconChainServerV1.GetGenesis).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/states/{state_id}/finality_checkpoints", beaconChainServerV1.GetFinalityCheckpoints).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/states/{state_id}/validators", beaconChainServerV1.GetValidators).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/states/{state_id}/validators/{validator_id}", beaconChainServerV1.GetValidator).Methods(http.MethodGet)
s.cfg.Router.HandleFunc("/eth/v1/beacon/states/{state_id}/validator_balances", beaconChainServerV1.GetValidatorBalances).Methods(http.MethodGet)
ethpbv1alpha1.RegisterNodeServer(s.grpcServer, nodeServer)
ethpbservice.RegisterBeaconNodeServer(s.grpcServer, nodeServerEth)

View File

@@ -63,6 +63,9 @@ func (s *Service) registerForUpcomingFork(currEpoch primitives.Epoch) error {
if nextEpoch == params.BeaconConfig().AltairForkEpoch {
s.registerRPCHandlersAltair()
}
if nextEpoch == params.BeaconConfig().DenebForkEpoch {
s.registerRPCHandlersDeneb()
}
}
return nil
}

View File

@@ -143,6 +143,50 @@ func TestService_CheckForNextEpochFork(t *testing.T) {
}
},
},
{
name: "deneb fork in the next epoch",
svcCreator: func(t *testing.T) *Service {
peer2peer := p2ptest.NewTestP2P(t)
gt := time.Now().Add(-4 * oneEpoch())
vr := [32]byte{'A'}
chainService := &mockChain.ChainService{
Genesis: gt,
ValidatorsRoot: vr,
}
bCfg := params.BeaconConfig().Copy()
bCfg.DenebForkEpoch = 5
params.OverrideBeaconConfig(bCfg)
params.BeaconConfig().InitializeForkSchedule()
ctx, cancel := context.WithCancel(context.Background())
r := &Service{
ctx: ctx,
cancel: cancel,
cfg: &config{
p2p: peer2peer,
chain: chainService,
clock: startup.NewClock(gt, vr),
initialSync: &mockSync.Sync{IsSyncing: false},
},
chainStarted: abool.New(),
subHandler: newSubTopicHandler(),
}
return r
},
currEpoch: 4,
wantErr: false,
postSvcCheck: func(t *testing.T, s *Service) {
genRoot := s.cfg.clock.GenesisValidatorsRoot()
digest, err := forks.ForkDigestFromEpoch(5, genRoot[:])
assert.NoError(t, err)
assert.Equal(t, true, s.subHandler.digestExists(digest))
rpcMap := make(map[string]bool)
for _, p := range s.cfg.p2p.Host().Mux().Protocols() {
rpcMap[string(p)] = true
}
assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRangeTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist")
assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRootTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -5,12 +5,14 @@ go_library(
srcs = [
"api.go",
"file.go",
"log.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/genesis",
visibility = ["//visibility:public"],
deps = [
"//api/client/beacon:go_default_library",
"//beacon-chain/db:go_default_library",
"//crypto/hash:go_default_library",
"//io/file:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -3,8 +3,6 @@ package genesis
import (
"context"
log "github.com/sirupsen/logrus"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api/client/beacon"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
"github.com/prysmaticlabs/prysm/v4/io/file"
"github.com/pkg/errors"
@@ -42,6 +43,9 @@ func (fi *FileInitializer) Initialize(ctx context.Context, d db.Database) error
if err != nil {
return errors.Wrapf(err, "error reading state file %s for checkpoint sync init", fi.statePath)
}
log.WithField(
"hash", fmt.Sprintf("%#x", hash.FastSum256(serState)),
).Info("Loading genesis state from disk.")
return d.LoadGenesis(ctx, serState)
}

View File

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

View File

@@ -162,8 +162,10 @@ func (s *Service) processFetchedDataRegSync(
invalidBlocks := 0
blksWithoutParentCount := 0
for _, b := range data.bwb {
if err := s.cfg.DB.SaveBlobSidecar(ctx, b.Blobs); err != nil {
log.WithError(err).Warn("Failed to save blob sidecar")
if len(b.Blobs) > 0 {
if err := s.cfg.DB.SaveBlobSidecar(ctx, b.Blobs); err != nil {
log.WithError(err).Warn("Failed to save blob sidecar")
}
}
if err := s.processBlock(ctx, genesis, b, blockReceiver); err != nil {

View File

@@ -138,6 +138,12 @@ var (
Help: "Time for gossiped blocks to arrive",
},
)
blobSidecarArrivalGossipSummary = promauto.NewSummary(
prometheus.SummaryOpts{
Name: "gossip_blob_sidecar_arrival_milliseconds",
Help: "Time for gossiped blob sidecars to arrive",
},
)
// Sync committee verification performance.
syncMessagesForUnknownBlocks = promauto.NewCounter(

View File

@@ -3,6 +3,7 @@ package sync
import (
"context"
"encoding/hex"
"fmt"
"sort"
"sync"
"time"
@@ -19,7 +20,6 @@ import (
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/encoding/ssz/equality"
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"github.com/sirupsen/logrus"
"github.com/trailofbits/go-mutexasserts"
@@ -100,6 +100,12 @@ func (s *Service) processPendingBlocks(ctx context.Context) error {
span.End()
return err
}
// No need to process the same block if we are already processing it
if s.cfg.chain.BlockBeingSynced(blkRoot) {
rootString := fmt.Sprintf("%#x", blkRoot)
log.WithField("BlockRoot", rootString).Info("Skipping pending block already being processed")
continue
}
inDB := s.cfg.beaconDB.HasBlock(ctx, blkRoot)
// No need to process the same block twice.
@@ -126,12 +132,12 @@ func (s *Service) processPendingBlocks(ctx context.Context) error {
continue
}
parentInDb := s.cfg.beaconDB.HasBlock(ctx, b.Block().ParentRoot())
parentRoot := b.Block().ParentRoot()
parentInDb := s.cfg.beaconDB.HasBlock(ctx, parentRoot)
hasPeer := len(pids) != 0
// Only request for missing parent block if it's not in beaconDB, not in pending cache
// and has peer in the peer list.
parentRoot := b.Block().ParentRoot()
if !inPendingQueue && !parentInDb && hasPeer {
log.WithFields(logrus.Fields{
"currentSlot": b.Block().Slot(),
@@ -241,6 +247,12 @@ func (s *Service) sendBatchRootRequest(ctx context.Context, roots [][32]byte, ra
ctx, span := trace.StartSpan(ctx, "sendBatchRootRequest")
defer span.End()
roots = dedupRoots(roots)
for i := len(roots) - 1; i >= 0; i-- {
if s.cfg.chain.BlockBeingSynced(roots[i]) {
roots = append(roots[:i], roots[i+1:]...)
}
}
if len(roots) == 0 {
return nil
}
@@ -249,7 +261,6 @@ func (s *Service) sendBatchRootRequest(ctx context.Context, roots [][32]byte, ra
if len(bestPeers) == 0 {
return nil
}
roots = dedupRoots(roots)
// Randomly choose a peer to query from our best peers. If that peer cannot return
// all the requested blocks, we randomly select another peer.
pid := bestPeers[randGen.Int()%len(bestPeers)]
@@ -428,21 +439,6 @@ func (s *Service) pendingBlocksInCache(slot primitives.Slot) []interfaces.ReadOn
return blks
}
// This returns signed blob sidecar given input key from slotToPendingBlobs.
func (s *Service) pendingBlobsInCache(slot primitives.Slot) []*eth.SignedBlobSidecar {
k := slotToCacheKey(slot)
value, ok := s.slotToPendingBlobs.Get(k)
if !ok {
return []*eth.SignedBlobSidecar{}
}
bs, ok := value.([]*eth.SignedBlobSidecar)
if !ok {
log.Debug("pendingBlobsInCache: value is not of type []*eth.SignedBlobSidecar")
return []*eth.SignedBlobSidecar{}
}
return bs
}
// This adds input signed beacon block to slotToPendingBlocks cache.
func (s *Service) addPendingBlockToCache(b interfaces.ReadOnlySignedBeaconBlock) error {
if err := blocks.BeaconBlockIsNil(b); err != nil {
@@ -461,23 +457,6 @@ func (s *Service) addPendingBlockToCache(b interfaces.ReadOnlySignedBeaconBlock)
return nil
}
// This adds blob to slotToPendingBlobs cache.
func (s *Service) addPendingBlobToCache(b *eth.SignedBlobSidecar) error {
blobs := s.pendingBlobsInCache(b.Message.Slot)
// If we already have seen the index. Ignore it.
for _, blob := range blobs {
if blob.Message.Index == b.Message.Index {
return nil
}
}
blobs = append(blobs, b)
k := slotToCacheKey(b.Message.Slot)
s.slotToPendingBlobs.Set(k, blobs, pendingBlockExpTime)
return nil
}
// This converts input string to slot.
func cacheKeyToSlot(s string) primitives.Slot {
b := []byte(s)

View File

@@ -30,6 +30,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
logTest "github.com/sirupsen/logrus/hooks/test"
)
// /- b1 - b2
@@ -846,3 +847,40 @@ func TestService_ProcessBadPendingBlocks(t *testing.T) {
// remove with a different block from the same slot.
require.NoError(t, r.deleteBlockFromPendingQueue(b.Block.Slot, bB, b1Root))
}
func TestAlreadySyncingBlock(t *testing.T) {
ctx := context.Background()
db := dbtest.SetupDB(t)
hook := logTest.NewGlobal()
mockChain := &mock.ChainService{
FinalizedCheckPoint: &ethpb.Checkpoint{
Epoch: 0,
},
}
p1 := p2ptest.NewTestP2P(t)
r := &Service{
cfg: &config{
p2p: p1,
beaconDB: db,
chain: mockChain,
clock: startup.NewClock(time.Unix(0, 0), [32]byte{}),
stateGen: stategen.New(db, doublylinkedtree.New()),
},
slotToPendingBlocks: gcache.New(time.Second, 2*time.Second),
seenPendingBlocks: make(map[[32]byte]bool),
}
r.initCaches()
b := util.NewBeaconBlock()
b.Block.Slot = 2
bRoot, err := b.Block.HashTreeRoot()
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
require.NoError(t, r.insertBlockToPendingQueue(b.Block.Slot, wsb, bRoot))
mockChain.SyncingRoot = bRoot
require.NoError(t, r.processPendingBlocks(ctx))
require.LogsContain(t, hook, "Skipping pending block already being processed")
}

View File

@@ -233,6 +233,7 @@ func TestSendRequest_SendBeaconBlocksByRangeRequest(t *testing.T) {
break
}
wsb, err := blocks.NewSignedBeaconBlock(knownBlocks[i])
require.NoError(t, err)
err = WriteBlockChunk(stream, startup.NewClock(time.Now(), [32]byte{}), p2.Encoding(), wsb)
if err != nil && err.Error() != network.ErrReset.Error() {
require.NoError(t, err)

View File

@@ -113,7 +113,6 @@ type Service struct {
ctx context.Context
cancel context.CancelFunc
slotToPendingBlocks *gcache.Cache
slotToPendingBlobs *gcache.Cache
seenPendingBlocks map[[32]byte]bool
blkRootToPendingAtts map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof
subHandler *subTopicHandler
@@ -152,7 +151,6 @@ type Service struct {
// NewService initializes new regular sync service.
func NewService(ctx context.Context, opts ...Option) *Service {
c := gcache.New(pendingBlockExpTime /* exp time */, 2*pendingBlockExpTime /* prune time */)
pendingBlobCache := gcache.New(0 /* exp time */, 0 /* prune time */)
ctx, cancel := context.WithCancel(ctx)
r := &Service{
ctx: ctx,
@@ -160,7 +158,6 @@ func NewService(ctx context.Context, opts ...Option) *Service {
chainStarted: abool.New(),
cfg: &config{clock: startup.NewClock(time.Unix(0, 0), [32]byte{})},
slotToPendingBlocks: c,
slotToPendingBlobs: pendingBlobCache,
seenPendingBlocks: make(map[[32]byte]bool),
blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
signatureChan: make(chan *signatureVerifier, verifierLimit),

View File

@@ -4,6 +4,8 @@ import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
opfeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/operation"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"google.golang.org/protobuf/proto"
)
@@ -22,5 +24,11 @@ func (s *Service) blobSubscriber(ctx context.Context, msg proto.Message) error {
s.cfg.chain.SendNewBlobEvent([32]byte(b.Message.BlockRoot), b.Message.Index)
s.cfg.operationNotifier.OperationFeed().Send(&feed.Event{
Type: opfeed.BlobSidecarReceived,
Data: &opfeed.BlobSidecarReceivedData{
Blob: b,
},
})
return nil
}

View File

@@ -77,10 +77,6 @@ func (s *Service) validateBlob(ctx context.Context, pid peer.ID, msg *pubsub.Mes
// [IGNORE] The sidecar's block's parent (defined by sidecar.block_parent_root) has been seen (via both gossip and non-gossip sources)
parentRoot := bytesutil.ToBytes32(blob.BlockParentRoot)
if !s.cfg.chain.HasBlock(ctx, parentRoot) {
if err := s.addPendingBlobToCache(sBlob); err != nil {
log.WithError(err).WithFields(blobFields(blob)).Error("Failed to add blob to cache")
return pubsub.ValidationIgnore, err
}
log.WithFields(blobFields(blob)).Debug("Ignored blob: parent block not found")
return pubsub.ValidationIgnore, nil
}
@@ -133,9 +129,13 @@ func (s *Service) validateBlob(ctx context.Context, pid peer.ID, msg *pubsub.Mes
return pubsub.ValidationIgnore, err
}
fields := blobFields(blob)
fields["sinceSlotStartTime"] = receivedTime.Sub(startTime)
sinceSlotStartTime := receivedTime.Sub(startTime)
fields["sinceSlotStartTime"] = sinceSlotStartTime
fields["validationTime"] = prysmTime.Now().Sub(receivedTime)
log.WithFields(fields).Debug("Received blob sidecar gossip")
blobSidecarArrivalGossipSummary.Observe(float64(sinceSlotStartTime.Milliseconds()))
msg.ValidatorData = sBlob
return pubsub.ValidationAccept, nil

View File

@@ -9,7 +9,6 @@ import (
pubsub "github.com/libp2p/go-libp2p-pubsub"
pb "github.com/libp2p/go-libp2p-pubsub/pb"
gcache "github.com/patrickmn/go-cache"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
dbtest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
@@ -27,7 +26,6 @@ import (
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestValidateBlob_FromSelf(t *testing.T) {
@@ -136,49 +134,12 @@ func TestValidateBlob_OlderThanFinalizedEpoch(t *testing.T) {
require.Equal(t, result, pubsub.ValidationIgnore)
}
func TestValidateBlob_UnknownParentBlock(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}}
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
chain: chainService,
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot)}}
b := util.NewBlobsidecar()
b.Message.Slot = chainService.CurrentSlot() + 1
buf := new(bytes.Buffer)
_, err := p.Encoding().EncodeGossip(buf, b)
require.NoError(t, err)
topic := p2p.GossipTypeMapping[reflect.TypeOf(b)]
digest, err := s.currentForkDigest()
require.NoError(t, err)
topic = s.addDigestAndIndexToTopic(topic, digest, 0)
result, err := s.validateBlob(ctx, "", &pubsub.Message{
Message: &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
}})
require.NoError(t, err)
require.Equal(t, result, pubsub.ValidationIgnore)
require.LogsContain(t, hook, "Ignored blob: parent block not found")
pendingBlobs := s.pendingBlobsInCache(b.Message.Slot)
require.Equal(t, 1, len(pendingBlobs))
}
func TestValidateBlob_HigherThanParentSlot(t *testing.T) {
db := dbtest.SetupDB(t)
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
@@ -222,7 +183,6 @@ func TestValidateBlob_InvalidProposerSignature(t *testing.T) {
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
stateGen := stategen.New(db, doublylinkedtree.New())
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
@@ -269,8 +229,7 @@ func TestValidateBlob_AlreadySeenInCache(t *testing.T) {
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
stateGen := stategen.New(db, doublylinkedtree.New())
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
seenBlobCache: lruwrpr.New(10),
seenBlobCache: lruwrpr.New(10),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
@@ -320,8 +279,7 @@ func TestValidateBlob_IncorrectProposerIndex(t *testing.T) {
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
stateGen := stategen.New(db, doublylinkedtree.New())
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
seenBlobCache: lruwrpr.New(10),
seenBlobCache: lruwrpr.New(10),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
@@ -370,8 +328,7 @@ func TestValidateBlob_EverythingPasses(t *testing.T) {
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
stateGen := stategen.New(db, doublylinkedtree.New())
s := &Service{
slotToPendingBlobs: gcache.New(time.Second, 2*time.Second),
seenBlobCache: lruwrpr.New(10),
seenBlobCache: lruwrpr.New(10),
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},

View File

@@ -62,7 +62,7 @@ var (
aggregateFirstInterval = &cli.DurationFlag{
Name: "aggregate-first-interval",
Usage: "(Advanced): Specifies the first interval in which attestations are aggregated in the slot (typically unnaggregated attestations are aggregated in this interval)",
Value: 6500 * time.Millisecond,
Value: 7000 * time.Millisecond,
Hidden: true,
}
aggregateSecondInterval = &cli.DurationFlag{

View File

@@ -8,11 +8,14 @@ func UseHoleskyNetworkConfig() {
cfg.ContractDeploymentBlock = 0
cfg.BootstrapNodes = []string{
// EF
"enr:-Iq4QJk4WqRkjsX5c2CXtOra6HnxN-BMXnWhmhEQO9Bn9iABTJGdjUOurM7Btj1ouKaFkvTRoju5vz2GPmVON2dffQKGAX53x8JigmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk",
"enr:-KG4QMH842KsJOZAHxI98VJcf8oPr1U8Ylyp2Tb-sNAPniWSCaxIS4F9gc3lGOnROEok7g5qrOm8WgJTl2WXx8MhMmIMhGV0aDKQqX6DZjABcAAKAAAAAAAAAIJpZIJ2NIJpcISygIjpiXNlY3AyNTZrMaECvQMvoDF46BfJgvAbbv1hwpNu9VQBXRIpHS_B8zmkZmmDdGNwgiMog3VkcIIjKA",
"enr:-Ly4QDU8tZeygxz1gEeAD4EKe4H_8gg-IanpTY6h8A1YGPv5BPNvCMD77zjHUk_iF1pfG_8DC6jYWbIOD1k5kF-LaG4Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCpfoNmMAFwAAoAAAAAAAAAgmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQN4bUae9DwIcq_56DNztksQYXeddTDKRonI5qI3YhN4SohzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
"enr:-Ku4QFo-9q73SspYI8cac_4kTX7yF800VXqJW4Lj3HkIkb5CMqFLxciNHePmMt4XdJzHvhrCC5ADI4D_GkAsxGJRLnQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAhnTT-AQFwAP__________gmlkgnY0gmlwhLKAiOmJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyk",
"enr:-Ku4QPG7F72mbKx3gEQEx07wpYYusGDh-ni6SNkLvOS-hhN-BxIggN7tKlmalb0L5JPoAfqD-akTZ-gX06hFeBEz4WoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpAhnTT-AQFwAP__________gmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyk",
"enr:-LK4QPxe-mDiSOtEB_Y82ozvxn9aQM07Ui8A-vQHNgYGMMthfsfOabaaTHhhJHFCBQQVRjBww_A5bM1rf8MlkJU_l68Eh2F0dG5ldHOIAADAAAAAAACEZXRoMpBpt9l0BAFwAAABAAAAAAAAgmlkgnY0gmlwhLKAiOmJc2VjcDI1NmsxoQJu6T9pclPObAzEVQ53DpVQqjadmVxdTLL-J3h9NFoCeIN0Y3CCIyiDdWRwgiMo",
"enr:-Ly4QGbOw4xNel5EhmDsJJ-QhC9XycWtsetnWoZ0uRy381GHdHsNHJiCwDTOkb3S1Ade0SFQkWJX_pgb3g8Jfh93rvMBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBpt9l0BAFwAAABAAAAAAAAgmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQOxKv9sv3zKF8GDewgFGGHKP5HCZZpPpTrwl9eXKAWGxIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
// Teku
"enr:-LK4QMlzEff6d-M0A1pSFG5lJ2c56i_I-ZftdojZbW3ehkGNM4pkQuHQqzVvF1BG9aDjIakjnmO23mCBFFZ2w5zOsugEh2F0dG5ldHOIAAAAAAYAAACEZXRoMpCpfoNmMAFwAAABAAAAAAAAgmlkgnY0gmlwhKyuI_mJc2VjcDI1NmsxoQIH1kQRCZW-4AIVyAeXj5o49m_IqNFKRHp6tSpfXMUrSYN0Y3CCIyiDdWRwgiMo",
"enr:-LS4QG0uV4qvcpJ-HFDJRGBmnlD3TJo7yc4jwK8iP7iKaTlfQ5kZvIDspLMJhk7j9KapuL9yyHaZmwTEZqr10k9XumyCEcmHYXR0bmV0c4gAAAAABgAAAIRldGgykGm32XQEAXAAAAEAAAAAAACCaWSCdjSCaXCErK4j-YlzZWNwMjU2azGhAgfWRBEJlb7gAhXIB5ePmjj2b8io0UpEenq1Kl9cxStJg3RjcIIjKIN1ZHCCIyg",
// Sigma Prime
"enr:-Le4QLoE1wFHSlGcm48a9ZESb_MRLqPPu6G0vHqu4MaUcQNDHS69tsy-zkN0K6pglyzX8m24mkb-LtBcbjAYdP1uxm4BhGV0aDKQabfZdAQBcAAAAQAAAAAAAIJpZIJ2NIJpcIQ5gR6Wg2lwNpAgAUHQBwEQAAAAAAAAADR-iXNlY3AyNTZrMaEDPMSNdcL92uNIyCsS177Z6KTXlbZakQqxv3aQcWawNXeDdWRwgiMohHVkcDaCI4I",
}
OverrideBeaconNetworkConfig(cfg)
}
@@ -20,19 +23,19 @@ func UseHoleskyNetworkConfig() {
// HoleskyConfig defines the config for the Holesky beacon chain testnet.
func HoleskyConfig() *BeaconChainConfig {
cfg := MainnetConfig().Copy()
cfg.MinGenesisTime = 1694786100
cfg.MinGenesisTime = 1695902100
cfg.GenesisDelay = 300
cfg.ConfigName = HoleskyName
cfg.GenesisForkVersion = []byte{0x00, 0x01, 0x70, 0x00}
cfg.GenesisForkVersion = []byte{0x01, 0x01, 0x70, 0x00}
cfg.SecondsPerETH1Block = 14
cfg.DepositChainID = 17000
cfg.DepositNetworkID = 17000
cfg.AltairForkEpoch = 0
cfg.AltairForkVersion = []byte{0x10, 0x1, 0x70, 0x0}
cfg.AltairForkVersion = []byte{0x2, 0x1, 0x70, 0x0}
cfg.BellatrixForkEpoch = 0
cfg.BellatrixForkVersion = []byte{0x20, 0x1, 0x70, 0x0}
cfg.BellatrixForkVersion = []byte{0x3, 0x1, 0x70, 0x0}
cfg.CapellaForkEpoch = 256
cfg.CapellaForkVersion = []byte{0x30, 0x1, 0x70, 0x0}
cfg.CapellaForkVersion = []byte{0x4, 0x1, 0x70, 0x0}
cfg.DenebForkEpoch = math.MaxUint64
cfg.DenebForkVersion = []byte{0x40, 0x1, 0x70, 0x0}
cfg.TerminalTotalDifficulty = "0"

View File

@@ -63,7 +63,7 @@ func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlock, error) {
case *eth.SignedBlindedBeaconBlockDeneb:
return initBlindedSignedBlockFromProtoDeneb(b)
case *eth.GenericSignedBeaconBlock_BlindedDeneb:
return initBlindedSignedBlockFromProtoDeneb(b.BlindedDeneb.Block)
return initBlindedSignedBlockFromProtoDeneb(b.BlindedDeneb.SignedBlindedBlock)
default:
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", i)
}
@@ -191,7 +191,7 @@ func BuildSignedBeaconBlock(blk interfaces.ReadOnlyBeaconBlock, signature []byte
if !ok {
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBlindedBeaconBlockDeneb{Block: pb, Signature: signature})
return NewSignedBeaconBlock(&eth.SignedBlindedBeaconBlockDeneb{Message: pb, Signature: signature})
}
pb, ok := pb.(*eth.BeaconBlockDeneb)
if !ok {

View File

@@ -142,7 +142,7 @@ func Test_NewSignedBeaconBlock(t *testing.T) {
})
t.Run("SignedBlindedBeaconBlockDeneb", func(t *testing.T) {
pb := &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Body: &eth.BlindedBeaconBlockBodyDeneb{}}}
b, err := NewSignedBeaconBlock(pb)
require.NoError(t, err)
@@ -152,8 +152,8 @@ func Test_NewSignedBeaconBlock(t *testing.T) {
t.Run("GenericSignedBeaconBlock_BlindedDeneb", func(t *testing.T) {
pb := &eth.GenericSignedBeaconBlock_BlindedDeneb{
BlindedDeneb: &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
SignedBlindedBlock: &eth.SignedBlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Body: &eth.BlindedBeaconBlockBodyDeneb{},
}}}}
b, err := NewSignedBeaconBlock(pb)
@@ -520,9 +520,9 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
header, err := PayloadToHeaderDeneb(wrapped)
require.NoError(t, err)
blindedBlock := &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Body: &eth.BlindedBeaconBlockBodyDeneb{}}}
blindedBlock.Block.Body.ExecutionPayloadHeader = header
blindedBlock.Message.Body.ExecutionPayloadHeader = header
blk, err := NewSignedBeaconBlock(blindedBlock)
require.NoError(t, err)

View File

@@ -121,7 +121,7 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
if b.IsBlinded() {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: &eth.SignedBlindedBeaconBlockAndBlobsDeneb{
Block: pb.(*eth.SignedBlindedBeaconBlockDeneb),
SignedBlindedBlock: pb.(*eth.SignedBlindedBeaconBlockDeneb),
}},
}, nil
}
@@ -310,7 +310,7 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
}
return initBlindedSignedBlockFromProtoDeneb(
&eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Slot: b.block.slot,
ProposerIndex: b.block.proposerIndex,
ParentRoot: b.block.parentRoot[:],

View File

@@ -113,7 +113,7 @@ func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
}
}
return &eth.SignedBlindedBeaconBlockDeneb{
Block: block,
Message: block,
Signature: b.signature[:],
}, nil
}
@@ -576,7 +576,7 @@ func initBlindedSignedBlockFromProtoDeneb(pb *eth.SignedBlindedBeaconBlockDeneb)
return nil, errNilBlock
}
block, err := initBlindedBlockFromProtoDeneb(pb.Block)
block, err := initBlindedBlockFromProtoDeneb(pb.Message)
if err != nil {
return nil, err
}

View File

@@ -274,7 +274,7 @@ func Test_SignedBeaconBlock_Proto(t *testing.T) {
})
t.Run("DenebBlind", func(t *testing.T) {
expectedBlock := &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
@@ -830,7 +830,7 @@ func Test_initSignedBlockFromProtoDeneb(t *testing.T) {
func Test_initBlindedSignedBlockFromProtoDeneb(t *testing.T) {
f := getFields()
expectedBlock := &eth.SignedBlindedBeaconBlockDeneb{
Block: &eth.BlindedBeaconBlockDeneb{
Message: &eth.BlindedBeaconBlockDeneb{
Slot: 128,
ProposerIndex: 128,
ParentRoot: f.root[:],
@@ -843,7 +843,7 @@ func Test_initBlindedSignedBlockFromProtoDeneb(t *testing.T) {
require.NoError(t, err)
resultHTR, err := resultBlock.block.HashTreeRoot()
require.NoError(t, err)
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
expectedHTR, err := expectedBlock.Message.HashTreeRoot()
require.NoError(t, err)
assert.DeepEqual(t, expectedHTR, resultHTR)
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature[:])

View File

@@ -29,7 +29,7 @@ func NewSignedBeaconBlockFromGeneric(gb *eth.GenericSignedBeaconBlock) (interfac
case *eth.GenericSignedBeaconBlock_Deneb:
return blocks.NewSignedBeaconBlock(bb.Deneb.Block)
case *eth.GenericSignedBeaconBlock_BlindedDeneb:
return blocks.NewSignedBeaconBlock(bb.BlindedDeneb.Block)
return blocks.NewSignedBeaconBlock(bb.BlindedDeneb.SignedBlindedBlock)
// Generic Signed Beacon Block Deneb can't be used here as it is not a block, but block content with blobs
default:
return nil, errors.Wrapf(blocks.ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", gb)

View File

@@ -22,6 +22,72 @@ const (
Withdrawal
)
func (s ValidatorStatus) String() string {
switch s {
case PendingInitialized:
return "pending_initialized"
case PendingQueued:
return "pending_queued"
case ActiveOngoing:
return "active_ongoing"
case ActiveExiting:
return "active_exiting"
case ActiveSlashed:
return "active_slashed"
case ExitedUnslashed:
return "exited_unslashed"
case ExitedSlashed:
return "exited_slashed"
case WithdrawalPossible:
return "withdrawal_possible"
case WithdrawalDone:
return "withdrawal_done"
case Active:
return "active"
case Pending:
return "pending"
case Exited:
return "exited"
case Withdrawal:
return "withdrawal"
default:
return "unknown"
}
}
func ValidatorStatusFromString(s string) (bool, ValidatorStatus) {
switch s {
case "pending_initialized":
return true, PendingInitialized
case "pending_queued":
return true, PendingQueued
case "active_ongoing":
return true, ActiveOngoing
case "active_exiting":
return true, ActiveExiting
case "active_slashed":
return true, ActiveSlashed
case "exited_unslashed":
return true, ExitedUnslashed
case "exited_slashed":
return true, ExitedSlashed
case "withdrawal_possible":
return true, WithdrawalPossible
case "withdrawal_done":
return true, WithdrawalDone
case "active":
return true, Active
case "pending":
return true, Pending
case "exited":
return true, Exited
case "withdrawal":
return true, Withdrawal
default:
return false, -1
}
}
type SyncCommitteeSubscription struct {
ValidatorIndex primitives.ValidatorIndex
SyncCommitteeIndices []uint64

130
deps.bzl
View File

@@ -41,6 +41,13 @@ def prysm_deps():
version = "v0.1.3",
)
go_repository(
name = "com_github_aclements_go_moremath",
importpath = "github.com/aclements/go-moremath",
sum = "h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g=",
version = "v0.0.0-20210112150236-f10218a38794",
)
go_repository(
name = "com_github_afex_hystrix_go",
importpath = "github.com/afex/hystrix-go",
@@ -394,6 +401,7 @@ def prysm_deps():
sum = "h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=",
version = "v1.3.1",
)
go_repository(
name = "com_github_bradfitz_go_smtpd",
importpath = "github.com/bradfitz/go-smtpd",
@@ -438,8 +446,8 @@ def prysm_deps():
go_repository(
name = "com_github_burntsushi_toml",
importpath = "github.com/BurntSushi/toml",
sum = "h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=",
version = "v1.2.1",
sum = "h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=",
version = "v1.3.2",
)
go_repository(
name = "com_github_burntsushi_xgb",
@@ -543,6 +551,7 @@ def prysm_deps():
sum = "h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=",
version = "v0.0.0-20200109182630-33d98a066a53",
)
go_repository(
name = "com_github_cloudykit_jet_v3",
importpath = "github.com/CloudyKit/jet/v3",
@@ -572,8 +581,8 @@ def prysm_deps():
go_repository(
name = "com_github_cockroachdb_datadriven",
importpath = "github.com/cockroachdb/datadriven",
sum = "h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=",
version = "v1.0.2",
sum = "h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o=",
version = "v1.0.3-0.20230801171734-e384cf455877",
)
go_repository(
name = "com_github_cockroachdb_errors",
@@ -591,8 +600,8 @@ def prysm_deps():
go_repository(
name = "com_github_cockroachdb_pebble",
importpath = "github.com/cockroachdb/pebble",
sum = "h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk=",
version = "v0.0.0-20230209160836-829675f94811",
sum = "h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w=",
version = "v0.0.0-20230906160148-46873a6a7a06",
)
go_repository(
name = "com_github_cockroachdb_redact",
@@ -830,12 +839,14 @@ def prysm_deps():
sum = "h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=",
version = "v0.0.0-20190423205320-6a90982ecee2",
)
go_repository(
name = "com_github_dgryski_go_sip13",
importpath = "github.com/dgryski/go-sip13",
sum = "h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=",
version = "v0.0.0-20181026042036-e10d5fee7954",
)
go_repository(
name = "com_github_dlclark_regexp2",
importpath = "github.com/dlclark/regexp2",
@@ -851,8 +862,8 @@ def prysm_deps():
go_repository(
name = "com_github_docker_docker",
importpath = "github.com/docker/docker",
sum = "h1:HlFGsy+9/xrgMmhmN+NGhCc5SHGJ7I+kHosRR1xc/aI=",
version = "v1.6.2",
sum = "h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=",
version = "v24.0.5+incompatible",
)
go_repository(
@@ -878,8 +889,8 @@ def prysm_deps():
go_repository(
name = "com_github_dop251_goja",
importpath = "github.com/dop251/goja",
sum = "h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE=",
version = "v0.0.0-20230605162241-28ee0ee714f3",
sum = "h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo=",
version = "v0.0.0-20230806174421-c933cf95e127",
)
go_repository(
name = "com_github_dop251_goja_nodejs",
@@ -1012,8 +1023,8 @@ def prysm_deps():
patches = [
"//third_party:com_github_ethereum_go_ethereum_secp256k1.patch",
],
sum = "h1:eGHJ4ij7oyVqUQn48LBz3B7pvQ8sV0wGJiIE6gDq/6Y=",
version = "v1.12.2",
sum = "h1:UF2FaUKPIy5jeZk3X06ait3y2Q4wI+vJ1l7+UARp+60=",
version = "v1.13.1",
)
go_repository(
@@ -1061,6 +1072,7 @@ def prysm_deps():
sum = "h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=",
version = "v0.0.0-20190710130421-bcb5799ab5e5",
)
go_repository(
name = "com_github_flosch_pongo2_v4",
importpath = "github.com/flosch/pongo2/v4",
@@ -1331,6 +1343,7 @@ def prysm_deps():
sum = "h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=",
version = "v0.19.5",
)
go_repository(
name = "com_github_go_playground_assert_v2",
importpath = "github.com/go-playground/assert/v2",
@@ -1592,8 +1605,8 @@ def prysm_deps():
go_repository(
name = "com_github_google_martian_v3",
importpath = "github.com/google/martian/v3",
sum = "h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=",
version = "v3.0.0",
sum = "h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60=",
version = "v3.1.0",
)
go_repository(
name = "com_github_google_pprof",
@@ -1607,6 +1620,7 @@ def prysm_deps():
sum = "h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=",
version = "v0.1.0",
)
go_repository(
name = "com_github_google_subcommands",
importpath = "github.com/google/subcommands",
@@ -1734,6 +1748,12 @@ def prysm_deps():
sum = "h1:4wctORg/1TkgLgXejv9yOSAm3cDBJxoTzl/RNuZmX28=",
version = "v2.3.1-0.20230315201114-09284ba20446",
)
go_repository(
name = "com_github_guptarohit_asciigraph",
importpath = "github.com/guptarohit/asciigraph",
sum = "h1:ccFnUF8xYIOUPPY3tmdvRyHqmn1MYI9iv1pLKX+/ZkQ=",
version = "v0.5.5",
)
go_repository(
name = "com_github_hashicorp_consul_api",
@@ -1894,8 +1914,8 @@ def prysm_deps():
go_repository(
name = "com_github_holiman_goevmlab",
importpath = "github.com/holiman/goevmlab",
sum = "h1:I5Cp9Y1fugGwcNGVVc69Fmgho0fkmtDHl6cej51+PJM=",
version = "v0.0.0-20230705203227-bf95bd5b9b75",
sum = "h1:K56eEHgH3CcQma/sZnZi9apLYD1gsUVTK9xc9QWVaac=",
version = "v0.0.0-20230917164918-f3777d0b880b",
)
go_repository(
@@ -1920,8 +1940,8 @@ def prysm_deps():
go_repository(
name = "com_github_huin_goupnp",
importpath = "github.com/huin/goupnp",
sum = "h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU=",
version = "v1.1.0",
sum = "h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=",
version = "v1.3.0",
)
go_repository(
name = "com_github_huin_goutil",
@@ -2095,6 +2115,7 @@ def prysm_deps():
sum = "h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=",
version = "v2.0.0+incompatible",
)
go_repository(
name = "com_github_iris_contrib_jade",
importpath = "github.com/iris-contrib/jade",
@@ -2143,8 +2164,8 @@ def prysm_deps():
go_repository(
name = "com_github_jedisct1_go_minisign",
importpath = "github.com/jedisct1/go-minisign",
sum = "h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U=",
version = "v0.0.0-20190909160543-45766022959e",
sum = "h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY=",
version = "v0.0.0-20230811132847-661be99b8267",
)
go_repository(
@@ -2239,6 +2260,7 @@ def prysm_deps():
sum = "h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=",
version = "v0.0.0-20180109212912-720a0952cc2a",
)
go_repository(
name = "com_github_julienschmidt_httprouter",
importpath = "github.com/julienschmidt/httprouter",
@@ -2296,6 +2318,7 @@ def prysm_deps():
sum = "h1:grB/oCf5baZhmYIeDMfgN3LYrtEcmK8pbxlRvEZ2pgw=",
version = "v12.2.0-beta5",
)
go_repository(
name = "com_github_kataras_neffos",
importpath = "github.com/kataras/neffos",
@@ -2710,6 +2733,7 @@ def prysm_deps():
sum = "h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=",
version = "v1.0.4",
)
go_repository(
name = "com_github_mediocregopher_radix_v3",
importpath = "github.com/mediocregopher/radix/v3",
@@ -2729,6 +2753,12 @@ def prysm_deps():
sum = "h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg=",
version = "v1.0.21",
)
go_repository(
name = "com_github_microsoft_go_winio",
importpath = "github.com/Microsoft/go-winio",
sum = "h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=",
version = "v0.6.1",
)
go_repository(
name = "com_github_miekg_dns",
@@ -2764,8 +2794,8 @@ def prysm_deps():
go_repository(
name = "com_github_minio_highwayhash",
importpath = "github.com/minio/highwayhash",
sum = "h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=",
version = "v1.0.1",
sum = "h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=",
version = "v1.0.2",
)
go_repository(
name = "com_github_minio_sha256_simd",
@@ -2985,6 +3015,7 @@ def prysm_deps():
sum = "h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI=",
version = "v0.3.2",
)
go_repository(
name = "com_github_nats_io_nats_go",
importpath = "github.com/nats-io/nats.go",
@@ -3022,6 +3053,7 @@ def prysm_deps():
sum = "h1:eFXv9Nu1lGbrNbj619aWwZfVF5HBrm9Plte8aNptuTI=",
version = "v0.0.0-20151028013722-8c68805598ab",
)
go_repository(
name = "com_github_nishanths_predeclared",
importpath = "github.com/nishanths/predeclared",
@@ -3297,6 +3329,7 @@ def prysm_deps():
sum = "h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=",
version = "v1.1.1",
)
go_repository(
name = "com_github_prashantv_gostub",
importpath = "github.com/prashantv/gostub",
@@ -3530,6 +3563,7 @@ def prysm_deps():
sum = "h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=",
version = "v2.1.0",
)
go_repository(
name = "com_github_ryanuber_columnize",
importpath = "github.com/ryanuber/columnize",
@@ -3562,6 +3596,7 @@ def prysm_deps():
sum = "h1:nMinx+JaEm/zJz4cEyClQeAw5rsYSB5th3xv+5lV6Vg=",
version = "v3.3.4",
)
go_repository(
name = "com_github_sean_seed",
importpath = "github.com/sean-/seed",
@@ -3588,6 +3623,7 @@ def prysm_deps():
sum = "h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=",
version = "v3.21.11+incompatible",
)
go_repository(
name = "com_github_shopify_goreferrer",
importpath = "github.com/Shopify/goreferrer",
@@ -3734,6 +3770,7 @@ def prysm_deps():
sum = "h1:YGaxtkYjb8mnTvtufv2LKLwCQu2/C7qFB7UtrOlTWOY=",
version = "v0.0.0-20180125191416-49c67e49c537",
)
go_repository(
name = "com_github_shurcool_webdavfs",
importpath = "github.com/shurcooL/webdavfs",
@@ -3948,14 +3985,14 @@ def prysm_deps():
go_repository(
name = "com_github_tklauser_go_sysconf",
importpath = "github.com/tklauser/go-sysconf",
sum = "h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=",
version = "v0.3.11",
sum = "h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=",
version = "v0.3.12",
)
go_repository(
name = "com_github_tklauser_numcpus",
importpath = "github.com/tklauser/numcpus",
sum = "h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=",
version = "v0.6.0",
sum = "h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=",
version = "v0.6.1",
)
go_repository(
@@ -4013,8 +4050,8 @@ def prysm_deps():
go_repository(
name = "com_github_urfave_cli_v2",
importpath = "github.com/urfave/cli/v2",
sum = "h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw=",
version = "v2.25.1",
sum = "h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=",
version = "v2.25.7",
)
go_repository(
name = "com_github_urfave_negroni",
@@ -5229,8 +5266,8 @@ def prysm_deps():
go_repository(
name = "io_etcd_go_bbolt",
importpath = "go.etcd.io/bbolt",
sum = "h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=",
version = "v1.3.5",
sum = "h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=",
version = "v1.3.6",
)
go_repository(
name = "io_etcd_go_etcd",
@@ -5299,6 +5336,7 @@ def prysm_deps():
sum = "h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=",
version = "v0.0.0-20201110183641-67b214c5f920",
)
go_repository(
name = "io_nhooyr_websocket",
importpath = "nhooyr.io/websocket",
@@ -5363,6 +5401,7 @@ def prysm_deps():
sum = "h1:iNBHGw1VvPJxH2B6RiFWFZ+vsjo1lCdRszBeOuwGi00=",
version = "v0.3.0",
)
go_repository(
name = "org_go4",
importpath = "go4.org",
@@ -5379,8 +5418,8 @@ def prysm_deps():
go_repository(
name = "org_golang_google_api",
importpath = "google.golang.org/api",
sum = "h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A=",
version = "v0.34.0",
sum = "h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA=",
version = "v0.44.0",
)
go_repository(
name = "org_golang_google_appengine",
@@ -5425,8 +5464,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_crypto",
importpath = "golang.org/x/crypto",
sum = "h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=",
version = "v0.9.0",
sum = "h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=",
version = "v0.12.0",
)
go_repository(
name = "org_golang_x_exp",
@@ -5476,8 +5515,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_perf",
importpath = "golang.org/x/perf",
sum = "h1:xYq6+9AtI+xP3M4r0N1hCkHrInHDBohhquRgx9Kk6gI=",
version = "v0.0.0-20180704124530-6e6d33e29852",
sum = "h1:ObuXPmIgI4ZMyQLIz48cJYgSyWdjUXc2SZAdyJMwEAU=",
version = "v0.0.0-20230113213139-801c7ef9e5c5",
)
go_repository(
@@ -5489,21 +5528,21 @@ def prysm_deps():
go_repository(
name = "org_golang_x_sys",
importpath = "golang.org/x/sys",
sum = "h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=",
version = "v0.9.0",
sum = "h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=",
version = "v0.11.0",
)
go_repository(
name = "org_golang_x_term",
importpath = "golang.org/x/term",
sum = "h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=",
version = "v0.8.0",
sum = "h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=",
version = "v0.11.0",
)
go_repository(
name = "org_golang_x_text",
importpath = "golang.org/x/text",
sum = "h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=",
version = "v0.9.0",
sum = "h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=",
version = "v0.12.0",
)
go_repository(
name = "org_golang_x_time",
@@ -5598,6 +5637,13 @@ def prysm_deps():
sum = "h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=",
version = "v1.24.0",
)
go_repository(
name = "tools_gotest_v3",
importpath = "gotest.tools/v3",
sum = "h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=",
version = "v3.5.0",
)
http_archive(
name = "com_github_supranational_blst",
urls = [

View File

@@ -512,7 +512,7 @@ func signedTestBlockDeneb(t *testing.T, slot primitives.Slot) interfaces.ReadOnl
func signedTestBlindedBlockDeneb(t *testing.T, slot primitives.Slot) interfaces.ReadOnlySignedBeaconBlock {
b := util.NewBlindedBeaconBlockDeneb()
b.Block.Slot = slot
b.Message.Slot = slot
s, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
return s

34
go.mod
View File

@@ -14,7 +14,7 @@ require (
github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018
github.com/dustin/go-humanize v1.0.0
github.com/emicklei/dot v0.11.0
github.com/ethereum/go-ethereum v1.12.2
github.com/ethereum/go-ethereum v1.13.1
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
github.com/fsnotify/fsnotify v1.6.0
github.com/ghodss/yaml v1.0.0
@@ -46,7 +46,7 @@ require (
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/manifoldco/promptui v0.7.0
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
github.com/minio/highwayhash v1.0.1
github.com/minio/highwayhash v1.0.2
github.com/minio/sha256-simd v1.0.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/multiformats/go-multiaddr v0.9.0
@@ -73,15 +73,15 @@ require (
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.25.1
github.com/urfave/cli/v2 v2.25.7
github.com/uudashr/gocognit v1.0.5
github.com/wealdtech/go-bytesutil v1.1.1
github.com/wealdtech/go-eth2-util v1.6.3
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3
go.etcd.io/bbolt v1.3.5
go.etcd.io/bbolt v1.3.6
go.opencensus.io v0.24.0
go.uber.org/automaxprocs v1.5.2
golang.org/x/crypto v0.9.0
golang.org/x/crypto v0.12.0
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad
golang.org/x/mod v0.11.0
golang.org/x/sync v0.3.0
@@ -97,8 +97,9 @@ require (
)
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/VictoriaMetrics/fastcache v1.12.0 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -109,7 +110,7 @@ require (
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 // indirect
github.com/cockroachdb/redact v1.1.3 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.10.0 // indirect
@@ -123,7 +124,7 @@ require (
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect
github.com/elastic/gosigar v0.14.2 // indirect
github.com/ethereum/c-kzg-4844 v0.3.1 // indirect
github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9 // indirect
@@ -147,8 +148,8 @@ require (
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/goevmlab v0.0.0-20230705203227-bf95bd5b9b75 // indirect
github.com/huin/goupnp v1.1.0 // indirect
github.com/holiman/goevmlab v0.0.0-20230917164918-f3777d0b880b // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
@@ -219,8 +220,8 @@ require (
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect
github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
@@ -232,13 +233,12 @@ require (
go.uber.org/zap v1.24.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/term v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
nhooyr.io/websocket v1.8.7 // indirect
@@ -256,8 +256,8 @@ require (
github.com/go-playground/validator/v10 v10.13.0
github.com/peterh/liner v1.2.0 // indirect
github.com/prysmaticlabs/gohashtree v0.0.3-alpha
golang.org/x/sys v0.9.0 // indirect
google.golang.org/api v0.34.0 // indirect
golang.org/x/sys v0.11.0 // indirect
google.golang.org/api v0.44.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
k8s.io/klog/v2 v2.80.0 // indirect
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect

120
go.sum
View File

@@ -18,6 +18,11 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -61,8 +66,9 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
@@ -75,6 +81,8 @@ github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20221202121132-bd37e8fb1d0d h1:DyFN
github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20221202121132-bd37e8fb1d0d/go.mod h1:BSKhCg8phwi9taTm849mjagbJqs5fpFFXCc6uH4qaT4=
github.com/MariusVanDerWijden/tx-fuzz v1.0.2 h1:H/C75+C305sWTF2ZoC4wZlJrMOpQ1YIdUBPL48ILIWI=
github.com/MariusVanDerWijden/tx-fuzz v1.0.2/go.mod h1:jrK+Lr2mr1+6Pm3LlQ6rGHgK3WRQ9VMTiX+2mPMe6ys=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -187,17 +195,18 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o=
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk=
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM=
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w=
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s=
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
@@ -269,8 +278,8 @@ github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/docker v1.6.2 h1:HlFGsy+9/xrgMmhmN+NGhCc5SHGJ7I+kHosRR1xc/aI=
github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@@ -278,8 +287,8 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE=
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@@ -305,6 +314,7 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@@ -312,8 +322,8 @@ github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj
github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg=
github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum/go-ethereum v1.12.2 h1:eGHJ4ij7oyVqUQn48LBz3B7pvQ8sV0wGJiIE6gDq/6Y=
github.com/ethereum/go-ethereum v1.12.2/go.mod h1:1cRAEV+rp/xX0zraSCBnu9Py3HQ+geRMj3HdR+k0wfI=
github.com/ethereum/go-ethereum v1.13.1 h1:UF2FaUKPIy5jeZk3X06ait3y2Q4wI+vJ1l7+UARp+60=
github.com/ethereum/go-ethereum v1.13.1/go.mod h1:xHQKzwkHSl0gnSjZK1mWa06XEdm9685AHqhRknOzqGQ=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -474,6 +484,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -491,6 +502,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@@ -532,6 +544,7 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -539,6 +552,10 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4=
@@ -625,8 +642,8 @@ github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZ
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/goevmlab v0.0.0-20221201133036-b31966a5267d/go.mod h1:tQJ4EfAokPShVDyEwKslIWKyt0qA/z8u+iK3kAwO424=
github.com/holiman/goevmlab v0.0.0-20221207202144-89074274e1b7/go.mod h1:t5n9hEKnVqrEclta+MoEDjI2D9X7bi8OiWGmyYuNhMk=
github.com/holiman/goevmlab v0.0.0-20230705203227-bf95bd5b9b75 h1:I5Cp9Y1fugGwcNGVVc69Fmgho0fkmtDHl6cej51+PJM=
github.com/holiman/goevmlab v0.0.0-20230705203227-bf95bd5b9b75/go.mod h1:z2Lgbrti+/tEP5LlI/K1Phv6EDhEkdQVa1XPUjMApcU=
github.com/holiman/goevmlab v0.0.0-20230917164918-f3777d0b880b h1:K56eEHgH3CcQma/sZnZi9apLYD1gsUVTK9xc9QWVaac=
github.com/holiman/goevmlab v0.0.0-20230917164918-f3777d0b880b/go.mod h1:Xf54jEqUJ0PwTEF9Z6e8FSLpnLpyB0QUfdHA3you/sw=
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o=
@@ -635,8 +652,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU=
github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279 h1:IpTHAzWv1pKDDWeJDY5VOHvqc2T9d3C8cPKEf2VPqHE=
@@ -864,8 +881,8 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKo
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc=
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
@@ -1251,13 +1268,15 @@ github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 h1:+LynomhWB+14Plp/bOONEAZCtvCZk4leRbTvNzNVkL0=
@@ -1281,8 +1300,8 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw=
github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4=
github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA=
@@ -1331,8 +1350,9 @@ github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPR
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
@@ -1342,7 +1362,9 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -1400,8 +1422,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1443,6 +1465,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
@@ -1496,7 +1519,9 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -1522,6 +1547,12 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
@@ -1536,6 +1567,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
@@ -1604,14 +1636,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1643,16 +1680,17 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1664,8 +1702,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1737,7 +1775,11 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
@@ -1781,8 +1823,13 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A=
google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1835,7 +1882,16 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
@@ -1863,7 +1919,10 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
@@ -1915,7 +1974,6 @@ gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLv
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=

View File

@@ -1710,9 +1710,9 @@ type BlobsBundle struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4" ssz-size:"?,48"`
Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4" ssz-size:"?,48"`
Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4" ssz-size:"?,131072"`
KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"`
Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"`
Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"`
}
func (x *BlobsBundle) Reset() {
@@ -1773,9 +1773,9 @@ type BlindedBlobsBundle struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4" ssz-size:"?,48"`
Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4" ssz-size:"?,48"`
BlobRoots [][]byte `protobuf:"bytes,3,rep,name=blob_roots,json=blobRoots,proto3" json:"blob_roots,omitempty" ssz-max:"4" ssz-size:"?,32"`
KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"`
Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"`
BlobRoots [][]byte `protobuf:"bytes,3,rep,name=blob_roots,json=blobRoots,proto3" json:"blob_roots,omitempty" ssz-max:"4096" ssz-size:"?,32"`
}
func (x *BlindedBlobsBundle) Reset() {
@@ -2307,44 +2307,45 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{
0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x07, 0x61,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x95,
0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36,
0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x9e,
0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x39,
0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34,
0x38, 0x92, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38,
0x92, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x27, 0x0a,
0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5,
0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x01, 0x34, 0x52,
0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x12, 0x42, 0x6c, 0x69, 0x6e, 0x64,
0x65, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36, 0x0a,
0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38,
0x92, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92,
0xb5, 0x18, 0x01, 0x34, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2c, 0x0a, 0x0a,
0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c,
0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x33, 0x32, 0x92, 0xb5, 0x18, 0x01, 0x34, 0x52,
0x09, 0x62, 0x6c, 0x6f, 0x62, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x42, 0x6c,
0x6f, 0x62, 0x12, 0x1e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x64, 0x61,
0x74, 0x61, 0x22, 0x43, 0x0a, 0x14, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x61,
0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x75,
0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x42, 0x96, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e,
0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x67,
0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e,
0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34,
0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x70, 0x72, 0x6f,
0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f,
0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x06, 0x70, 0x72, 0x6f,
0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32,
0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22,
0xaa, 0x01, 0x0a, 0x12, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x73,
0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42,
0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39,
0x36, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x12, 0x28, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34,
0x30, 0x39, 0x36, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x62,
0x6c, 0x6f, 0x62, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42,
0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x33, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39,
0x36, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x04,
0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04,
0x64, 0x61, 0x74, 0x61, 0x22, 0x43, 0x0a, 0x14, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,
0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11,
0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
0x65, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x42, 0x96, 0x01, 0x0a, 0x16, 0x6f, 0x72,
0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e,
0x65, 0x2e, 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45,
0x6e, 0x67, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74,
0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b,
0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12,
0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -220,21 +220,21 @@ message Withdrawal {
// It consists of the necessary components for constructing a blobs sidecar object to gossip through p2p.
message BlobsBundle {
// The KZG commitments of the blobs.
repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
// The proofs of the blobs.
repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
// The blobs itself.
repeated bytes blobs = 3 [(ethereum.eth.ext.ssz_size) = "?,131072", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes blobs = 3 [(ethereum.eth.ext.ssz_size) = "?,131072", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
}
// BlindedBlobsBundle is retrieved through the builder-api from /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey} after the Deneb hardfork.
message BlindedBlobsBundle {
// The KZG commitments of the blobs.
repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
// The proofs of the blobs.
repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
// The blob roots.
repeated bytes blob_roots = 3 [(ethereum.eth.ext.ssz_size) = "?,32", (ethereum.eth.ext.ssz_max) = "4"];
repeated bytes blob_roots = 3 [(ethereum.eth.ext.ssz_size) = "?,32", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
}
// Blob contains the data that is to be committed on chain.

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: 86494c66845c0e5ec7b1a6c6f0e34a770ce57f86114b161b5e0d8c7b04219b77
// Hash: d163294d035463f410495773be37e7997f5305be52b9d58b513197b7b37d5124
package enginev1
import (
@@ -2439,8 +2439,8 @@ func (b *BlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
offset += len(b.Blobs) * 131072
// Field (0) 'KzgCommitments'
if size := len(b.KzgCommitments); size > 4 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4)
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
for ii := 0; ii < len(b.KzgCommitments); ii++ {
@@ -2452,8 +2452,8 @@ func (b *BlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
}
// Field (1) 'Proofs'
if size := len(b.Proofs); size > 4 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4)
if size := len(b.Proofs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4096)
return
}
for ii := 0; ii < len(b.Proofs); ii++ {
@@ -2465,8 +2465,8 @@ func (b *BlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
}
// Field (2) 'Blobs'
if size := len(b.Blobs); size > 4 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4)
if size := len(b.Blobs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4096)
return
}
for ii := 0; ii < len(b.Blobs); ii++ {
@@ -2513,7 +2513,7 @@ func (b *BlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (0) 'KzgCommitments'
{
buf = tail[o0:o1]
num, err := ssz.DivideInt2(len(buf), 48, 4)
num, err := ssz.DivideInt2(len(buf), 48, 4096)
if err != nil {
return err
}
@@ -2529,7 +2529,7 @@ func (b *BlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (1) 'Proofs'
{
buf = tail[o1:o2]
num, err := ssz.DivideInt2(len(buf), 48, 4)
num, err := ssz.DivideInt2(len(buf), 48, 4096)
if err != nil {
return err
}
@@ -2545,7 +2545,7 @@ func (b *BlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (2) 'Blobs'
{
buf = tail[o2:]
num, err := ssz.DivideInt2(len(buf), 131072, 4)
num, err := ssz.DivideInt2(len(buf), 131072, 4096)
if err != nil {
return err
}
@@ -2587,8 +2587,8 @@ func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
// Field (0) 'KzgCommitments'
{
if size := len(b.KzgCommitments); size > 4 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4)
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
subIndx := hh.Index()
@@ -2602,16 +2602,16 @@ func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.KzgCommitments))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}
// Field (1) 'Proofs'
{
if size := len(b.Proofs); size > 4 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4)
if size := len(b.Proofs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4096)
return
}
subIndx := hh.Index()
@@ -2625,16 +2625,16 @@ func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.Proofs))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}
// Field (2) 'Blobs'
{
if size := len(b.Blobs); size > 4 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4)
if size := len(b.Blobs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4096)
return
}
subIndx := hh.Index()
@@ -2648,9 +2648,9 @@ func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.Blobs))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}
@@ -2685,8 +2685,8 @@ func (b *BlindedBlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
offset += len(b.BlobRoots) * 32
// Field (0) 'KzgCommitments'
if size := len(b.KzgCommitments); size > 4 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4)
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
for ii := 0; ii < len(b.KzgCommitments); ii++ {
@@ -2698,8 +2698,8 @@ func (b *BlindedBlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
}
// Field (1) 'Proofs'
if size := len(b.Proofs); size > 4 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4)
if size := len(b.Proofs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4096)
return
}
for ii := 0; ii < len(b.Proofs); ii++ {
@@ -2711,8 +2711,8 @@ func (b *BlindedBlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) {
}
// Field (2) 'BlobRoots'
if size := len(b.BlobRoots); size > 4 {
err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4)
if size := len(b.BlobRoots); size > 4096 {
err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4096)
return
}
for ii := 0; ii < len(b.BlobRoots); ii++ {
@@ -2759,7 +2759,7 @@ func (b *BlindedBlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (0) 'KzgCommitments'
{
buf = tail[o0:o1]
num, err := ssz.DivideInt2(len(buf), 48, 4)
num, err := ssz.DivideInt2(len(buf), 48, 4096)
if err != nil {
return err
}
@@ -2775,7 +2775,7 @@ func (b *BlindedBlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (1) 'Proofs'
{
buf = tail[o1:o2]
num, err := ssz.DivideInt2(len(buf), 48, 4)
num, err := ssz.DivideInt2(len(buf), 48, 4096)
if err != nil {
return err
}
@@ -2791,7 +2791,7 @@ func (b *BlindedBlobsBundle) UnmarshalSSZ(buf []byte) error {
// Field (2) 'BlobRoots'
{
buf = tail[o2:]
num, err := ssz.DivideInt2(len(buf), 32, 4)
num, err := ssz.DivideInt2(len(buf), 32, 4096)
if err != nil {
return err
}
@@ -2833,8 +2833,8 @@ func (b *BlindedBlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
// Field (0) 'KzgCommitments'
{
if size := len(b.KzgCommitments); size > 4 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4)
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
subIndx := hh.Index()
@@ -2848,16 +2848,16 @@ func (b *BlindedBlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.KzgCommitments))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}
// Field (1) 'Proofs'
{
if size := len(b.Proofs); size > 4 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4)
if size := len(b.Proofs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 4096)
return
}
subIndx := hh.Index()
@@ -2871,16 +2871,16 @@ func (b *BlindedBlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.Proofs))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}
// Field (2) 'BlobRoots'
{
if size := len(b.BlobRoots); size > 4 {
err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4)
if size := len(b.BlobRoots); size > 4096 {
err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4096)
return
}
subIndx := hh.Index()
@@ -2894,9 +2894,9 @@ func (b *BlindedBlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
numItems := uint64(len(b.BlobRoots))
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4)
hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4096)
} else {
hh.MerkleizeWithMixin(subIndx, numItems, 4)
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,24 +39,6 @@ var _ = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch(0)
var _ = emptypb.Empty{}
var _ = empty.Empty{}
func request_BeaconChain_GetGenesis_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.GetGenesis(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_GetGenesis_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.GetGenesis(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconChain_GetWeakSubjectivity_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
@@ -129,280 +111,6 @@ func local_request_BeaconChain_GetStateRoot_0(ctx context.Context, marshaler run
}
func request_BeaconChain_GetFinalityCheckpoints_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
msg, err := client.GetFinalityCheckpoints(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_GetFinalityCheckpoints_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
msg, err := server.GetFinalityCheckpoints(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_ListValidators_0 = &utilities.DoubleArray{Encoding: map[string]int{"state_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
)
func request_BeaconChain_ListValidators_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateValidatorsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListValidators_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListValidators(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_ListValidators_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateValidatorsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListValidators_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListValidators(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconChain_GetValidator_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateValidatorRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
val, ok = pathParams["validator_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_id")
}
validator_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_id", err)
}
protoReq.ValidatorId = (validator_id)
msg, err := client.GetValidator(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_GetValidator_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.StateValidatorRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
val, ok = pathParams["validator_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "validator_id")
}
validator_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "validator_id", err)
}
protoReq.ValidatorId = (validator_id)
msg, err := server.GetValidator(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_ListValidatorBalances_0 = &utilities.DoubleArray{Encoding: map[string]int{"state_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
)
func request_BeaconChain_ListValidatorBalances_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.ValidatorBalancesRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListValidatorBalances_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListValidatorBalances(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_ListValidatorBalances_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.ValidatorBalancesRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["state_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "state_id")
}
state_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "state_id", err)
}
protoReq.StateId = (state_id)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListValidatorBalances_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListValidatorBalances(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_ListSyncCommittees_0 = &utilities.DoubleArray{Encoding: map[string]int{"state_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
)
@@ -547,96 +255,6 @@ func local_request_BeaconChain_GetRandao_0(ctx context.Context, marshaler runtim
}
var (
filter_BeaconChain_ListBlockHeaders_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconChain_ListBlockHeaders_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.BlockHeadersRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListBlockHeaders_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListBlockHeaders(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_ListBlockHeaders_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.BlockHeadersRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListBlockHeaders_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListBlockHeaders(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconChain_GetBlockHeader_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.BlockRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["block_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "block_id")
}
block_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "block_id", err)
}
protoReq.BlockId = (block_id)
msg, err := client.GetBlockHeader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_GetBlockHeader_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1.BlockRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["block_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "block_id")
}
block_id, err := runtime.Bytes(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "block_id", err)
}
protoReq.BlockId = (block_id)
msg, err := server.GetBlockHeader(ctx, &protoReq)
return msg, metadata, err
}
func request_BeaconChain_SubmitBlock_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq eth.SignedBeaconBlockContentsContainer
var metadata runtime.ServerMetadata
@@ -1349,29 +967,6 @@ func local_request_BeaconChain_GetSpec_0(ctx context.Context, marshaler runtime.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterBeaconChainHandlerFromEndpoint instead.
func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux, server BeaconChainServer) error {
mux.Handle("GET", pattern_BeaconChain_GetGenesis_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetGenesis")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_GetGenesis_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetGenesis_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1418,98 +1013,6 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_GetFinalityCheckpoints_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetFinalityCheckpoints")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_GetFinalityCheckpoints_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetFinalityCheckpoints_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListValidators")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_ListValidators_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetValidator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetValidator")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_GetValidator_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetValidator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListValidatorBalances_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListValidatorBalances")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_ListValidatorBalances_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListValidatorBalances_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListSyncCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1556,52 +1059,6 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListBlockHeaders")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_ListBlockHeaders_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListBlockHeaders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetBlockHeader_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetBlockHeader")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_GetBlockHeader_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetBlockHeader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_BeaconChain_SubmitBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -2080,26 +1537,6 @@ func RegisterBeaconChainHandler(ctx context.Context, mux *runtime.ServeMux, conn
// "BeaconChainClient" to call the correct interceptors.
func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux, client BeaconChainClient) error {
mux.Handle("GET", pattern_BeaconChain_GetGenesis_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetGenesis")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_GetGenesis_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetGenesis_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetWeakSubjectivity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -2140,86 +1577,6 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_GetFinalityCheckpoints_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetFinalityCheckpoints")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_GetFinalityCheckpoints_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetFinalityCheckpoints_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListValidators")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_ListValidators_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetValidator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetValidator")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_GetValidator_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetValidator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListValidatorBalances_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListValidatorBalances")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_ListValidatorBalances_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListValidatorBalances_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListSyncCommittees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -2260,46 +1617,6 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/ListBlockHeaders")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_ListBlockHeaders_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListBlockHeaders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_GetBlockHeader_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.BeaconChain/GetBlockHeader")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_GetBlockHeader_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_GetBlockHeader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_BeaconChain_SubmitBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -2684,28 +2001,14 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
}
var (
pattern_BeaconChain_GetGenesis_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "genesis"}, ""))
pattern_BeaconChain_GetWeakSubjectivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "weak_subjectivity"}, ""))
pattern_BeaconChain_GetStateRoot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "root"}, ""))
pattern_BeaconChain_GetFinalityCheckpoints_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "finality_checkpoints"}, ""))
pattern_BeaconChain_ListValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "validators"}, ""))
pattern_BeaconChain_GetValidator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "validators", "validator_id"}, ""))
pattern_BeaconChain_ListValidatorBalances_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "validator_balances"}, ""))
pattern_BeaconChain_ListSyncCommittees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "sync_committees"}, ""))
pattern_BeaconChain_GetRandao_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"internal", "eth", "v1", "beacon", "states", "state_id", "randao"}, ""))
pattern_BeaconChain_ListBlockHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "headers"}, ""))
pattern_BeaconChain_GetBlockHeader_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"internal", "eth", "v1", "beacon", "headers", "block_id"}, ""))
pattern_BeaconChain_SubmitBlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"internal", "eth", "v1", "beacon", "blocks"}, ""))
pattern_BeaconChain_SubmitBlockSSZ_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"internal", "eth", "v1", "beacon", "blocks", "ssz"}, ""))
@@ -2746,28 +2049,14 @@ var (
)
var (
forward_BeaconChain_GetGenesis_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetWeakSubjectivity_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetStateRoot_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetFinalityCheckpoints_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListValidators_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetValidator_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListValidatorBalances_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListSyncCommittees_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetRandao_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListBlockHeaders_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetBlockHeader_0 = runtime.ForwardResponseMessage
forward_BeaconChain_SubmitBlock_0 = runtime.ForwardResponseMessage
forward_BeaconChain_SubmitBlockSSZ_0 = runtime.ForwardResponseMessage

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