mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
5 Commits
backfill-r
...
v4.1.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d506f9b2da | ||
|
|
d55757500f | ||
|
|
41dff74e90 | ||
|
|
4f48c551da | ||
|
|
2f6dcb34b6 |
@@ -283,6 +283,42 @@ func TestClient_GetHeader(t *testing.T) {
|
||||
require.Equal(t, len(bundle.Proofs[i]) == 48, true)
|
||||
}
|
||||
})
|
||||
t.Run("deneb, no bundle", func(t *testing.T) {
|
||||
hc := &http.Client{
|
||||
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
|
||||
require.Equal(t, expectedPath, r.URL.Path)
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(bytes.NewBufferString(testExampleHeaderResponseDenebNoBundle)),
|
||||
Request: r.Clone(ctx),
|
||||
}, nil
|
||||
}),
|
||||
}
|
||||
c := &Client{
|
||||
hc: hc,
|
||||
baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"},
|
||||
}
|
||||
h, err := c.GetHeader(ctx, slot, bytesutil.ToBytes32(parentHash), bytesutil.ToBytes48(pubkey))
|
||||
require.NoError(t, err)
|
||||
expectedWithdrawalsRoot := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")
|
||||
bid, err := h.Message()
|
||||
require.NoError(t, err)
|
||||
bidHeader, err := bid.Header()
|
||||
require.NoError(t, err)
|
||||
withdrawalsRoot, err := bidHeader.WithdrawalsRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, bytes.Equal(expectedWithdrawalsRoot, withdrawalsRoot))
|
||||
value, err := stringToUint256("652312848583266388373324160190187140051835877600158453279131187530910662656")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fmt.Sprintf("%#x", value.SSZBytes()), fmt.Sprintf("%#x", bid.Value()))
|
||||
bidValue := bytesutil.ReverseByteOrder(bid.Value())
|
||||
require.DeepEqual(t, bidValue, value.Bytes())
|
||||
require.DeepEqual(t, big.NewInt(0).SetBytes(bidValue), value.Int)
|
||||
bundle, err := bid.BlindedBlobsBundle()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*v1.BlindedBlobsBundle)(nil), bundle)
|
||||
})
|
||||
|
||||
t.Run("unsupported version", func(t *testing.T) {
|
||||
hc := &http.Client{
|
||||
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
|
||||
|
||||
@@ -1131,9 +1131,12 @@ func (bb *BuilderBidDeneb) ToProto() (*eth.BuilderBidDeneb, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bundle, err := bb.BlindedBlobsBundle.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var bundle *v1.BlindedBlobsBundle
|
||||
if bb.BlindedBlobsBundle != nil {
|
||||
bundle, err = bb.BlindedBlobsBundle.ToProto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ð.BuilderBidDeneb{
|
||||
Header: header,
|
||||
|
||||
@@ -159,6 +159,36 @@ var testExampleHeaderResponseDeneb = `{
|
||||
}
|
||||
}`
|
||||
|
||||
var testExampleHeaderResponseDenebNoBundle = `{
|
||||
"version": "deneb",
|
||||
"data": {
|
||||
"message": {
|
||||
"header": {
|
||||
"parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09",
|
||||
"state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"block_number": "1",
|
||||
"gas_limit": "1",
|
||||
"gas_used": "1",
|
||||
"timestamp": "1",
|
||||
"extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"base_fee_per_gas": "452312848583266388373324160190187140051835877600158453279131187530910662656",
|
||||
"block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"withdrawals_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
"blob_gas_used": "1",
|
||||
"excess_blob_gas": "2"
|
||||
},
|
||||
"value": "652312848583266388373324160190187140051835877600158453279131187530910662656",
|
||||
"pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"
|
||||
},
|
||||
"signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"
|
||||
}
|
||||
}`
|
||||
|
||||
var testExampleHeaderResponseUnknownVersion = `{
|
||||
"version": "bad",
|
||||
"data": {
|
||||
|
||||
@@ -38,7 +38,6 @@ go_library(
|
||||
"//async/event:go_default_library",
|
||||
"//beacon-chain/blockchain/kzg:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/epoch/precompute:go_default_library",
|
||||
|
||||
@@ -3,7 +3,6 @@ package blockchain
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v4/async/event"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/execution"
|
||||
@@ -62,7 +61,7 @@ func WithExecutionEngineCaller(c execution.EngineCaller) Option {
|
||||
}
|
||||
|
||||
// WithDepositCache for deposit lifecycle after chain inclusion.
|
||||
func WithDepositCache(c *depositcache.DepositCache) Option {
|
||||
func WithDepositCache(c cache.DepositCache) Option {
|
||||
return func(s *Service) error {
|
||||
s.cfg.DepositCache = c
|
||||
return nil
|
||||
|
||||
@@ -265,6 +265,9 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []consensusblocks.ROBlo
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := s.databaseDACheck(ctx, b); err != nil {
|
||||
return errors.Wrap(err, "could not validate blob data availability")
|
||||
}
|
||||
args := &forkchoicetypes.BlockAndCheckpoints{Block: b.Block(),
|
||||
JustifiedCheckpoint: jCheckpoints[i],
|
||||
FinalizedCheckpoint: fCheckpoints[i]}
|
||||
@@ -330,6 +333,33 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []consensusblocks.ROBlo
|
||||
return s.saveHeadNoDB(ctx, lastB, lastBR, preState, !isValidPayload)
|
||||
}
|
||||
|
||||
func commitmentsToCheck(b consensusblocks.ROBlock, current primitives.Slot) [][]byte {
|
||||
if b.Version() < version.Deneb {
|
||||
return nil
|
||||
}
|
||||
// We are only required to check within MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS
|
||||
if !params.WithinDAPeriod(slots.ToEpoch(b.Block().Slot()), slots.ToEpoch(current)) {
|
||||
return nil
|
||||
}
|
||||
kzgCommitments, err := b.Block().Body().BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return kzgCommitments
|
||||
}
|
||||
|
||||
func (s *Service) databaseDACheck(ctx context.Context, b consensusblocks.ROBlock) error {
|
||||
commitments := commitmentsToCheck(b, s.CurrentSlot())
|
||||
if len(commitments) == 0 {
|
||||
return nil
|
||||
}
|
||||
sidecars, err := s.cfg.BeaconDB.BlobSidecarsByRoot(ctx, b.Root())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get blob sidecars")
|
||||
}
|
||||
return kzg.IsDataAvailable(commitments, sidecars)
|
||||
}
|
||||
|
||||
func (s *Service) updateEpochBoundaryCaches(ctx context.Context, st state.BeaconState) error {
|
||||
e := coreTime.CurrentEpoch(st)
|
||||
if err := helpers.UpdateCommitteeCache(ctx, st, e); err != nil {
|
||||
@@ -508,9 +538,10 @@ func (s *Service) isDataAvailable(ctx context.Context, root [32]byte, signed int
|
||||
return errors.New("invalid nil beacon block")
|
||||
}
|
||||
// We are only required to check within MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS
|
||||
if slots.ToEpoch(block.Slot())+params.BeaconNetworkConfig().MinEpochsForBlobsSidecarsRequest > primitives.Epoch(s.CurrentSlot()) {
|
||||
if !params.WithinDAPeriod(slots.ToEpoch(block.Slot()), slots.ToEpoch(s.CurrentSlot())) {
|
||||
return nil
|
||||
}
|
||||
|
||||
body := block.Body()
|
||||
if body == nil {
|
||||
return errors.New("invalid nil beacon block body")
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
forkchoicetypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/types"
|
||||
@@ -235,7 +236,8 @@ func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) {
|
||||
// to be included(rather than the last one to be processed). This was most likely
|
||||
// done as the state cannot represent signed integers.
|
||||
finalizedEth1DepIdx := eth1DepositIndex - 1
|
||||
if err = s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(finalizedEth1DepIdx)); err != nil {
|
||||
if err = s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(finalizedEth1DepIdx), common.Hash(finalizedState.Eth1Data().BlockHash),
|
||||
0 /* Setting a zero value as we have no access to block height */); err != nil {
|
||||
log.WithError(err).Error("could not insert finalized deposits")
|
||||
return
|
||||
}
|
||||
@@ -247,7 +249,7 @@ func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) {
|
||||
// to the provided eth1 deposit index.
|
||||
s.cfg.DepositCache.PrunePendingDeposits(ctx, int64(eth1DepositIndex)) // lint:ignore uintcast -- Deposit index should not exceed int64 in your lifetime.
|
||||
|
||||
log.WithField("duration", time.Since(startTime).String()).Debug("Finalized deposit insertion completed")
|
||||
log.WithField("duration", time.Since(startTime).String()).Debugf("Finalized deposit insertion completed at index %d", finalizedEth1DepIdx)
|
||||
}
|
||||
|
||||
// This ensures that the input root defaults to using genesis root instead of zero hashes. This is needed for handling
|
||||
|
||||
@@ -699,7 +699,7 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
||||
gs, _ := util.DeterministicGenesisState(t, 32)
|
||||
require.NoError(t, service.saveGenesisData(ctx, gs))
|
||||
gs = gs.Copy()
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10}))
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10, BlockHash: make([]byte, 32)}))
|
||||
assert.NoError(t, gs.SetEth1DepositIndex(8))
|
||||
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
||||
var zeroSig [96]byte
|
||||
@@ -713,8 +713,9 @@ func TestInsertFinalizedDeposits(t *testing.T) {
|
||||
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
|
||||
}
|
||||
service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'})
|
||||
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||
fDeposits, err := depositCache.FinalizedDeposits(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex()), "Finalized deposits not inserted correctly")
|
||||
deps := depositCache.AllDeposits(ctx, big.NewInt(107))
|
||||
for _, d := range deps {
|
||||
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||
@@ -728,7 +729,7 @@ func TestInsertFinalizedDeposits_PrunePendingDeposits(t *testing.T) {
|
||||
gs, _ := util.DeterministicGenesisState(t, 32)
|
||||
require.NoError(t, service.saveGenesisData(ctx, gs))
|
||||
gs = gs.Copy()
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10}))
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 10, BlockHash: make([]byte, 32)}))
|
||||
assert.NoError(t, gs.SetEth1DepositIndex(8))
|
||||
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
||||
var zeroSig [96]byte
|
||||
@@ -748,8 +749,9 @@ func TestInsertFinalizedDeposits_PrunePendingDeposits(t *testing.T) {
|
||||
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root))
|
||||
}
|
||||
service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'})
|
||||
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||
fDeposits, err := depositCache.FinalizedDeposits(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex()), "Finalized deposits not inserted correctly")
|
||||
deps := depositCache.AllDeposits(ctx, big.NewInt(107))
|
||||
for _, d := range deps {
|
||||
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||
@@ -767,11 +769,11 @@ func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
|
||||
gs, _ := util.DeterministicGenesisState(t, 32)
|
||||
require.NoError(t, service.saveGenesisData(ctx, gs))
|
||||
gs = gs.Copy()
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 7}))
|
||||
assert.NoError(t, gs.SetEth1Data(ðpb.Eth1Data{DepositCount: 7, BlockHash: make([]byte, 32)}))
|
||||
assert.NoError(t, gs.SetEth1DepositIndex(6))
|
||||
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
|
||||
gs2 := gs.Copy()
|
||||
assert.NoError(t, gs2.SetEth1Data(ðpb.Eth1Data{DepositCount: 15}))
|
||||
assert.NoError(t, gs2.SetEth1Data(ðpb.Eth1Data{DepositCount: 15, BlockHash: make([]byte, 32)}))
|
||||
assert.NoError(t, gs2.SetEth1DepositIndex(13))
|
||||
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}, gs2))
|
||||
var zeroSig [96]byte
|
||||
@@ -785,11 +787,11 @@ func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
|
||||
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
|
||||
}
|
||||
// Insert 3 deposits before hand.
|
||||
require.NoError(t, depositCache.InsertFinalizedDeposits(ctx, 2))
|
||||
|
||||
require.NoError(t, depositCache.InsertFinalizedDeposits(ctx, 2, [32]byte{}, 0))
|
||||
service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'})
|
||||
fDeposits := depositCache.FinalizedDeposits(ctx)
|
||||
assert.Equal(t, 5, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||
fDeposits, err := depositCache.FinalizedDeposits(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, int(fDeposits.MerkleTrieIndex()), "Finalized deposits not inserted correctly")
|
||||
|
||||
deps := depositCache.AllDeposits(ctx, big.NewInt(105))
|
||||
for _, d := range deps {
|
||||
@@ -798,8 +800,9 @@ func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
|
||||
|
||||
// Insert New Finalized State with higher deposit count.
|
||||
service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k', '2'})
|
||||
fDeposits = depositCache.FinalizedDeposits(ctx)
|
||||
assert.Equal(t, 12, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
|
||||
fDeposits, err = depositCache.FinalizedDeposits(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 12, int(fDeposits.MerkleTrieIndex()), "Finalized deposits not inserted correctly")
|
||||
deps = depositCache.AllDeposits(ctx, big.NewInt(112))
|
||||
for _, d := range deps {
|
||||
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/async/event"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/kzg"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
@@ -69,7 +68,7 @@ type config struct {
|
||||
BeaconBlockBuf int
|
||||
ChainStartFetcher execution.ChainStartFetcher
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
DepositCache *depositcache.DepositCache
|
||||
DepositCache cache.DepositCache
|
||||
ProposerSlotIndexCache *cache.ProposerPayloadIDsCache
|
||||
AttPool attestations.Pool
|
||||
ExitPool voluntaryexits.PoolManager
|
||||
|
||||
2
beacon-chain/cache/BUILD.bazel
vendored
2
beacon-chain/cache/BUILD.bazel
vendored
@@ -13,6 +13,7 @@ go_library(
|
||||
"common.go",
|
||||
"doc.go",
|
||||
"error.go",
|
||||
"interfaces.go",
|
||||
"payload_id.go",
|
||||
"proposer_indices.go",
|
||||
"proposer_indices_disabled.go", # keep
|
||||
@@ -44,6 +45,7 @@ go_library(
|
||||
"//math:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_hashicorp_golang_lru//:go_default_library",
|
||||
"@com_github_patrickmn_go_cache//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
3
beacon-chain/cache/depositcache/BUILD.bazel
vendored
3
beacon-chain/cache/depositcache/BUILD.bazel
vendored
@@ -13,12 +13,14 @@ go_library(
|
||||
"//testing/spectest:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
@@ -35,6 +37,7 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
|
||||
@@ -11,9 +11,11 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
@@ -30,20 +32,11 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
// DepositFetcher defines a struct which can retrieve deposit information from a store.
|
||||
type DepositFetcher interface {
|
||||
AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
|
||||
DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int)
|
||||
DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte)
|
||||
FinalizedDeposits(ctx context.Context) *FinalizedDeposits
|
||||
NonFinalizedDeposits(ctx context.Context, lastFinalizedIndex int64, untilBlk *big.Int) []*ethpb.Deposit
|
||||
}
|
||||
|
||||
// FinalizedDeposits stores the trie of deposits that have been included
|
||||
// in the beacon state up to the latest finalized checkpoint.
|
||||
type FinalizedDeposits struct {
|
||||
Deposits *trie.SparseMerkleTrie
|
||||
MerkleTrieIndex int64
|
||||
deposits *trie.SparseMerkleTrie
|
||||
merkleTrieIndex int64
|
||||
}
|
||||
|
||||
// DepositCache stores all in-memory deposit objects. This
|
||||
@@ -52,7 +45,7 @@ type DepositCache struct {
|
||||
// Beacon chain deposits in memory.
|
||||
pendingDeposits []*ethpb.DepositContainer
|
||||
deposits []*ethpb.DepositContainer
|
||||
finalizedDeposits *FinalizedDeposits
|
||||
finalizedDeposits FinalizedDeposits
|
||||
depositsByKey map[[fieldparams.BLSPubkeyLength]byte][]*ethpb.DepositContainer
|
||||
depositsLock sync.RWMutex
|
||||
}
|
||||
@@ -64,13 +57,13 @@ func New() (*DepositCache, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// finalizedDeposits.MerkleTrieIndex is initialized to -1 because it represents the index of the last trie item.
|
||||
// finalizedDeposits.merkleTrieIndex is initialized to -1 because it represents the index of the last trie item.
|
||||
// Inserting the first item into the trie will set the value of the index to 0.
|
||||
return &DepositCache{
|
||||
pendingDeposits: []*ethpb.DepositContainer{},
|
||||
deposits: []*ethpb.DepositContainer{},
|
||||
depositsByKey: map[[fieldparams.BLSPubkeyLength]byte][]*ethpb.DepositContainer{},
|
||||
finalizedDeposits: &FinalizedDeposits{Deposits: finalizedDepositsTrie, MerkleTrieIndex: -1},
|
||||
finalizedDeposits: FinalizedDeposits{deposits: finalizedDepositsTrie, merkleTrieIndex: -1},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -129,14 +122,15 @@ func (dc *DepositCache) InsertDepositContainers(ctx context.Context, ctrs []*eth
|
||||
}
|
||||
|
||||
// InsertFinalizedDeposits inserts deposits up to eth1DepositIndex (inclusive) into the finalized deposits cache.
|
||||
func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1DepositIndex int64) error {
|
||||
func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context,
|
||||
eth1DepositIndex int64, _ common.Hash, _ uint64) error {
|
||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.InsertFinalizedDeposits")
|
||||
defer span.End()
|
||||
dc.depositsLock.Lock()
|
||||
defer dc.depositsLock.Unlock()
|
||||
|
||||
depositTrie := dc.finalizedDeposits.Deposits
|
||||
insertIndex := int(dc.finalizedDeposits.MerkleTrieIndex + 1)
|
||||
depositTrie := dc.finalizedDeposits.Deposits()
|
||||
insertIndex := int(dc.finalizedDeposits.merkleTrieIndex + 1)
|
||||
|
||||
// Don't insert into finalized trie if there is no deposit to
|
||||
// insert.
|
||||
@@ -154,7 +148,7 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
|
||||
return nil
|
||||
}
|
||||
for _, d := range dc.deposits {
|
||||
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
|
||||
if d.Index <= dc.finalizedDeposits.merkleTrieIndex {
|
||||
continue
|
||||
}
|
||||
if d.Index > eth1DepositIndex {
|
||||
@@ -169,10 +163,13 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
|
||||
}
|
||||
insertIndex++
|
||||
}
|
||||
|
||||
dc.finalizedDeposits = &FinalizedDeposits{
|
||||
Deposits: depositTrie,
|
||||
MerkleTrieIndex: eth1DepositIndex,
|
||||
tree, ok := depositTrie.(*trie.SparseMerkleTrie)
|
||||
if !ok {
|
||||
return errors.New("not a sparse merkle tree")
|
||||
}
|
||||
dc.finalizedDeposits = FinalizedDeposits{
|
||||
deposits: tree,
|
||||
merkleTrieIndex: eth1DepositIndex,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -204,8 +201,6 @@ func (dc *DepositCache) AllDepositContainers(ctx context.Context) []*ethpb.Depos
|
||||
// AllDeposits returns a list of historical deposits until the given block number
|
||||
// (inclusive). If no block is specified then this method returns all historical deposits.
|
||||
func (dc *DepositCache) AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.AllDeposits")
|
||||
defer span.End()
|
||||
dc.depositsLock.RLock()
|
||||
defer dc.depositsLock.RUnlock()
|
||||
|
||||
@@ -261,16 +256,16 @@ func (dc *DepositCache) DepositByPubkey(ctx context.Context, pubKey []byte) (*et
|
||||
}
|
||||
|
||||
// FinalizedDeposits returns the finalized deposits trie.
|
||||
func (dc *DepositCache) FinalizedDeposits(ctx context.Context) *FinalizedDeposits {
|
||||
func (dc *DepositCache) FinalizedDeposits(ctx context.Context) (cache.FinalizedDeposits, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "DepositsCache.FinalizedDeposits")
|
||||
defer span.End()
|
||||
dc.depositsLock.RLock()
|
||||
defer dc.depositsLock.RUnlock()
|
||||
|
||||
return &FinalizedDeposits{
|
||||
Deposits: dc.finalizedDeposits.Deposits.Copy(),
|
||||
MerkleTrieIndex: dc.finalizedDeposits.MerkleTrieIndex,
|
||||
}
|
||||
deposits: dc.finalizedDeposits.deposits.Copy(),
|
||||
merkleTrieIndex: dc.finalizedDeposits.merkleTrieIndex,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NonFinalizedDeposits returns the list of non-finalized deposits until the given block number (inclusive).
|
||||
@@ -281,7 +276,7 @@ func (dc *DepositCache) NonFinalizedDeposits(ctx context.Context, lastFinalizedI
|
||||
dc.depositsLock.RLock()
|
||||
defer dc.depositsLock.RUnlock()
|
||||
|
||||
if dc.finalizedDeposits == nil {
|
||||
if dc.finalizedDeposits.Deposits() == nil {
|
||||
return dc.allDeposits(untilBlk)
|
||||
}
|
||||
|
||||
@@ -307,9 +302,6 @@ func (dc *DepositCache) PruneProofs(ctx context.Context, untilDepositIndex int64
|
||||
}
|
||||
|
||||
for i := untilDepositIndex; i >= 0; i-- {
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
// Finding a nil proof means that all proofs up to this deposit have been already pruned.
|
||||
if dc.deposits[i].Deposit.Proof == nil {
|
||||
break
|
||||
@@ -319,3 +311,14 @@ func (dc *DepositCache) PruneProofs(ctx context.Context, untilDepositIndex int64
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deposits returns the cached internal deposit tree.
|
||||
func (fd *FinalizedDeposits) Deposits() cache.MerkleTree {
|
||||
return fd.deposits
|
||||
}
|
||||
|
||||
// MerkleTrieIndex represents the last finalized index in
|
||||
// the finalized deposit container.
|
||||
func (fd *FinalizedDeposits) MerkleTrieIndex() int64 {
|
||||
return fd.merkleTrieIndex
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
|
||||
const nilDepositErr = "Ignoring nil deposit insertion"
|
||||
|
||||
var _ DepositFetcher = (*DepositCache)(nil)
|
||||
var _ cache.DepositFetcher = (*DepositCache)(nil)
|
||||
|
||||
func TestInsertDeposit_LogsOnNilDepositInsertion(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
@@ -416,11 +417,12 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
|
||||
Index: 3,
|
||||
})
|
||||
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2, [32]byte{}, 0))
|
||||
|
||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||
cachedDeposits, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex())
|
||||
|
||||
var deps [][]byte
|
||||
for _, d := range finalizedDeposits {
|
||||
@@ -432,7 +434,7 @@ func TestFinalizedDeposits_DepositsCachedCorrectly(t *testing.T) {
|
||||
require.NoError(t, err, "Could not generate deposit trie")
|
||||
rootA, err := generatedTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
|
||||
rootB, err := cachedDeposits.Deposits().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, rootA, rootB)
|
||||
}
|
||||
@@ -474,15 +476,16 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
||||
Index: 2,
|
||||
}
|
||||
dc.deposits = oldFinalizedDeposits
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1, [32]byte{}, 0))
|
||||
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2, [32]byte{}, 0))
|
||||
|
||||
dc.deposits = append(dc.deposits, []*ethpb.DepositContainer{newFinalizedDeposit}...)
|
||||
|
||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||
cachedDeposits, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||
assert.Equal(t, int64(1), cachedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(1), cachedDeposits.MerkleTrieIndex())
|
||||
|
||||
var deps [][]byte
|
||||
for _, d := range oldFinalizedDeposits {
|
||||
@@ -494,7 +497,7 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
|
||||
require.NoError(t, err, "Could not generate deposit trie")
|
||||
rootA, err := generatedTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
rootB, err := cachedDeposits.Deposits.HashTreeRoot()
|
||||
rootB, err := cachedDeposits.Deposits().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, rootA, rootB)
|
||||
}
|
||||
@@ -503,11 +506,12 @@ func TestFinalizedDeposits_HandleZeroDeposits(t *testing.T) {
|
||||
dc, err := New()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2, [32]byte{}, 0))
|
||||
|
||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||
cachedDeposits, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||
assert.Equal(t, int64(-1), cachedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(-1), cachedDeposits.MerkleTrieIndex())
|
||||
}
|
||||
|
||||
func TestFinalizedDeposits_HandleSmallerThanExpectedDeposits(t *testing.T) {
|
||||
@@ -548,11 +552,12 @@ func TestFinalizedDeposits_HandleSmallerThanExpectedDeposits(t *testing.T) {
|
||||
}
|
||||
dc.deposits = finalizedDeposits
|
||||
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 5))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 5, [32]byte{}, 0))
|
||||
|
||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||
cachedDeposits, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex())
|
||||
}
|
||||
|
||||
func TestFinalizedDeposits_HandleLowerEth1DepositIndex(t *testing.T) {
|
||||
@@ -623,14 +628,15 @@ func TestFinalizedDeposits_HandleLowerEth1DepositIndex(t *testing.T) {
|
||||
}
|
||||
dc.deposits = finalizedDeposits
|
||||
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 5))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 5, [32]byte{}, 0))
|
||||
|
||||
// Reinsert finalized deposits with a lower index.
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2, [32]byte{}, 0))
|
||||
|
||||
cachedDeposits := dc.FinalizedDeposits(context.Background())
|
||||
cachedDeposits, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cachedDeposits, "Deposits not cached")
|
||||
assert.Equal(t, int64(5), cachedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(5), cachedDeposits.MerkleTrieIndex())
|
||||
}
|
||||
|
||||
func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
|
||||
@@ -640,7 +646,7 @@ func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
|
||||
finalizedDeposits := dc.finalizedDeposits
|
||||
assert.NotNil(t, finalizedDeposits)
|
||||
assert.NotNil(t, finalizedDeposits.Deposits)
|
||||
assert.Equal(t, int64(-1), finalizedDeposits.MerkleTrieIndex)
|
||||
assert.Equal(t, int64(-1), finalizedDeposits.merkleTrieIndex)
|
||||
}
|
||||
|
||||
func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
|
||||
@@ -694,7 +700,7 @@ func TestNonFinalizedDeposits_ReturnsAllNonFinalizedDeposits(t *testing.T) {
|
||||
},
|
||||
Index: 3,
|
||||
})
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1, [32]byte{}, 0))
|
||||
|
||||
deps := dc.NonFinalizedDeposits(context.Background(), 1, nil)
|
||||
assert.Equal(t, 2, len(deps))
|
||||
@@ -751,7 +757,7 @@ func TestNonFinalizedDeposits_ReturnsNonFinalizedDepositsUpToBlockNumber(t *test
|
||||
},
|
||||
Index: 3,
|
||||
})
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 1, [32]byte{}, 0))
|
||||
|
||||
deps := dc.NonFinalizedDeposits(context.Background(), 1, big.NewInt(10))
|
||||
assert.Equal(t, 1, len(deps))
|
||||
@@ -799,41 +805,43 @@ func TestFinalizedDeposits_ReturnsTrieCorrectly(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Perform this in a non-sensical ordering
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 10))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 3))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 4))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 10, [32]byte{}, 0))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 2, [32]byte{}, 0))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 3, [32]byte{}, 0))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 4, [32]byte{}, 0))
|
||||
|
||||
// Mimic finalized deposit trie fetch.
|
||||
fd := dc.FinalizedDeposits(context.Background())
|
||||
deps := dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex, big.NewInt(14))
|
||||
insertIndex := fd.MerkleTrieIndex + 1
|
||||
fd, err := dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
deps := dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex(), big.NewInt(14))
|
||||
insertIndex := fd.MerkleTrieIndex() + 1
|
||||
|
||||
for _, dep := range deps {
|
||||
depHash, err := dep.Data.HashTreeRoot()
|
||||
assert.NoError(t, err)
|
||||
if err = fd.Deposits.Insert(depHash[:], int(insertIndex)); err != nil {
|
||||
if err = fd.Deposits().Insert(depHash[:], int(insertIndex)); err != nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
insertIndex++
|
||||
}
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 15))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 15))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 14))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 15, [32]byte{}, 0))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 15, [32]byte{}, 0))
|
||||
require.NoError(t, dc.InsertFinalizedDeposits(context.Background(), 14, [32]byte{}, 0))
|
||||
|
||||
fd = dc.FinalizedDeposits(context.Background())
|
||||
deps = dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex, big.NewInt(30))
|
||||
insertIndex = fd.MerkleTrieIndex + 1
|
||||
fd, err = dc.FinalizedDeposits(context.Background())
|
||||
require.NoError(t, err)
|
||||
deps = dc.NonFinalizedDeposits(context.Background(), fd.MerkleTrieIndex(), big.NewInt(30))
|
||||
insertIndex = fd.MerkleTrieIndex() + 1
|
||||
|
||||
for _, dep := range deps {
|
||||
depHash, err := dep.Data.HashTreeRoot()
|
||||
assert.NoError(t, err)
|
||||
if err = fd.Deposits.Insert(depHash[:], int(insertIndex)); err != nil {
|
||||
if err = fd.Deposits().Insert(depHash[:], int(insertIndex)); err != nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
insertIndex++
|
||||
}
|
||||
assert.Equal(t, fd.Deposits.NumOfItems(), depositTrie.NumOfItems())
|
||||
assert.Equal(t, fd.Deposits().NumOfItems(), depositTrie.NumOfItems())
|
||||
}
|
||||
|
||||
func TestPruneProofs_Ok(t *testing.T) {
|
||||
@@ -1056,3 +1064,11 @@ func makeDepositProof() [][]byte {
|
||||
}
|
||||
return proof
|
||||
}
|
||||
|
||||
func TestEmptyTree(t *testing.T) {
|
||||
finalizedDepositsTrie, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
|
||||
require.NoError(t, err)
|
||||
v, err := finalizedDepositsTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("%x", v)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestInsertPendingDeposit_OK(t *testing.T) {
|
||||
dc := DepositCache{}
|
||||
dc.InsertPendingDeposit(context.Background(), ðpb.Deposit{}, 111, 100, [32]byte{})
|
||||
|
||||
assert.Equal(t, 1, len(dc.pendingDeposits), "Deposit not inserted")
|
||||
assert.Equal(t, 1, len(dc.pendingDeposits), "deposit not inserted")
|
||||
}
|
||||
|
||||
func TestInsertPendingDeposit_ignoresNilDeposit(t *testing.T) {
|
||||
@@ -56,7 +56,7 @@ func TestRemovePendingDeposit_IgnoresNilDeposit(t *testing.T) {
|
||||
dc := DepositCache{}
|
||||
dc.pendingDeposits = []*ethpb.DepositContainer{{Deposit: ðpb.Deposit{}}}
|
||||
dc.RemovePendingDeposit(context.Background(), nil /*deposit*/)
|
||||
assert.Equal(t, 1, len(dc.pendingDeposits), "Deposit unexpectedly removed")
|
||||
assert.Equal(t, 1, len(dc.pendingDeposits), "deposit unexpectedly removed")
|
||||
}
|
||||
|
||||
func TestPendingDeposit_RoundTrip(t *testing.T) {
|
||||
|
||||
23
beacon-chain/cache/depositsnapshot/BUILD.bazel
vendored
23
beacon-chain/cache/depositsnapshot/BUILD.bazel
vendored
@@ -3,26 +3,37 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"deposit_fetcher.go",
|
||||
"deposit_inserter.go",
|
||||
"deposit_tree.go",
|
||||
"deposit_tree_snapshot.go",
|
||||
"merkle_tree.go",
|
||||
"zerohashes.gen.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_wealdtech_go_bytesutil//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"deposit_cache_test.go",
|
||||
"deposit_tree_snapshot_test.go",
|
||||
"merkle_tree_test.go",
|
||||
"spec_test.go",
|
||||
@@ -32,10 +43,16 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@in_gopkg_yaml_v3//:go_default_library",
|
||||
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
|
||||
|
||||
1199
beacon-chain/cache/depositsnapshot/deposit_cache_test.go
vendored
Normal file
1199
beacon-chain/cache/depositsnapshot/deposit_cache_test.go
vendored
Normal file
File diff suppressed because it is too large
Load Diff
304
beacon-chain/cache/depositsnapshot/deposit_fetcher.go
vendored
Normal file
304
beacon-chain/cache/depositsnapshot/deposit_fetcher.go
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/wealdtech/go-bytesutil"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
pendingDepositsCount = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "beacondb_pending_deposits_eip4881",
|
||||
Help: "The number of pending deposits in memory",
|
||||
})
|
||||
)
|
||||
|
||||
// Cache stores all in-memory deposit objects. This
|
||||
// stores all the deposit related data that is required by the beacon-node.
|
||||
type Cache struct {
|
||||
pendingDeposits []*ethpb.DepositContainer
|
||||
deposits []*ethpb.DepositContainer
|
||||
finalizedDeposits finalizedDepositsContainer
|
||||
depositsByKey map[[fieldparams.BLSPubkeyLength]byte][]*ethpb.DepositContainer
|
||||
depositsLock sync.RWMutex
|
||||
}
|
||||
|
||||
// finalizedDepositsContainer stores the trie of deposits that have been included
|
||||
// in the beacon state up to the latest finalized checkpoint.
|
||||
type finalizedDepositsContainer struct {
|
||||
depositTree *DepositTree
|
||||
merkleTrieIndex int64
|
||||
}
|
||||
|
||||
// New instantiates a new deposit cache
|
||||
func New() (*Cache, error) {
|
||||
finalizedDepositsTrie := NewDepositTree()
|
||||
|
||||
// finalizedDeposits.merkleTrieIndex is initialized to -1 because it represents the index of the last trie item.
|
||||
// Inserting the first item into the trie will set the value of the index to 0.
|
||||
return &Cache{
|
||||
pendingDeposits: []*ethpb.DepositContainer{},
|
||||
deposits: []*ethpb.DepositContainer{},
|
||||
depositsByKey: map[[fieldparams.BLSPubkeyLength]byte][]*ethpb.DepositContainer{},
|
||||
finalizedDeposits: toFinalizedDepositsContainer(finalizedDepositsTrie, -1),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AllDeposits returns a list of historical deposits until the given block number
|
||||
// (inclusive). If no block is specified then this method returns all historical deposits.
|
||||
func (c *Cache) AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
return c.allDeposits(untilBlk)
|
||||
}
|
||||
|
||||
func (c *Cache) allDeposits(untilBlk *big.Int) []*ethpb.Deposit {
|
||||
var deposits []*ethpb.Deposit
|
||||
for _, ctnr := range c.deposits {
|
||||
cBlk := big.NewInt(0).SetUint64(ctnr.Eth1BlockHeight)
|
||||
if untilBlk == nil || untilBlk.Cmp(cBlk) >= 0 {
|
||||
deposits = append(deposits, ctnr.Deposit)
|
||||
}
|
||||
}
|
||||
return deposits
|
||||
}
|
||||
|
||||
// AllDepositContainers returns all historical deposit containers.
|
||||
func (c *Cache) AllDepositContainers(ctx context.Context) []*ethpb.DepositContainer {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.AllDepositContainers")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
// Make a shallow copy of the deposits and return that. This way, the
|
||||
// caller can safely iterate over the returned list of deposits without
|
||||
// the possibility of new deposits showing up. If we were to return the
|
||||
// list without a copy, when a new deposit is added to the cache, it
|
||||
// would also be present in the returned value. This could result in a
|
||||
// race condition if the list is being iterated over.
|
||||
//
|
||||
// It's not necessary to make a deep copy of this list because the
|
||||
// deposits in the cache should never be modified. It is still possible
|
||||
// for the caller to modify one of the underlying deposits and modify
|
||||
// the cache, but that's not a race condition. Also, a deep copy would
|
||||
// take too long and use too much memory.
|
||||
deposits := make([]*ethpb.DepositContainer, len(c.deposits))
|
||||
copy(deposits, c.deposits)
|
||||
return deposits
|
||||
}
|
||||
|
||||
// DepositByPubkey looks through historical deposits and finds one which contains
|
||||
// a certain public key within its deposit data.
|
||||
func (c *Cache) DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.DepositByPubkey")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
var deposit *ethpb.Deposit
|
||||
var blockNum *big.Int
|
||||
deps, ok := c.depositsByKey[bytesutil.ToBytes48(pubKey)]
|
||||
if !ok || len(deps) == 0 {
|
||||
return deposit, blockNum
|
||||
}
|
||||
// We always return the first deposit if a particular
|
||||
// validator key has multiple deposits assigned to
|
||||
// it.
|
||||
deposit = deps[0].Deposit
|
||||
blockNum = big.NewInt(int64(deps[0].Eth1BlockHeight))
|
||||
return deposit, blockNum
|
||||
}
|
||||
|
||||
// DepositsNumberAndRootAtHeight returns number of deposits made up to blockheight and the
|
||||
// root that corresponds to the latest deposit at that blockheight.
|
||||
func (c *Cache) DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.DepositsNumberAndRootAtHeight")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
heightIdx := sort.Search(len(c.deposits), func(i int) bool {
|
||||
dBlkHeight := big.NewInt(0).SetUint64(c.deposits[i].Eth1BlockHeight)
|
||||
return dBlkHeight.Cmp(blockHeight) > 0
|
||||
})
|
||||
// send the deposit root of the empty trie, if eth1follow distance is greater than the time of the earliest
|
||||
// deposit.
|
||||
if heightIdx == 0 {
|
||||
return 0, [32]byte{}
|
||||
}
|
||||
return uint64(heightIdx), bytesutil.ToBytes32(c.deposits[heightIdx-1].DepositRoot)
|
||||
}
|
||||
|
||||
// FinalizedDeposits returns the finalized deposits trie.
|
||||
func (c *Cache) FinalizedDeposits(ctx context.Context) (cache.FinalizedDeposits, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.FinalizedDeposits")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
tree, err := c.finalizedDeposits.depositTree.Copy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &finalizedDepositsContainer{
|
||||
depositTree: tree,
|
||||
merkleTrieIndex: c.finalizedDeposits.merkleTrieIndex,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NonFinalizedDeposits returns the list of non-finalized deposits until the given block number (inclusive).
|
||||
// If no block is specified then this method returns all non-finalized deposits.
|
||||
func (c *Cache) NonFinalizedDeposits(ctx context.Context, lastFinalizedIndex int64, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.NonFinalizedDeposits")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
if c.finalizedDeposits.depositTree == nil {
|
||||
return c.allDeposits(untilBlk)
|
||||
}
|
||||
|
||||
var deposits []*ethpb.Deposit
|
||||
for _, d := range c.deposits {
|
||||
if (d.Index > lastFinalizedIndex) && (untilBlk == nil || untilBlk.Uint64() >= d.Eth1BlockHeight) {
|
||||
deposits = append(deposits, d.Deposit)
|
||||
}
|
||||
}
|
||||
|
||||
return deposits
|
||||
}
|
||||
|
||||
// PruneProofs removes proofs from all deposits whose index is equal or less than untilDepositIndex.
|
||||
func (c *Cache) PruneProofs(ctx context.Context, untilDepositIndex int64) error {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.PruneProofs")
|
||||
defer span.End()
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
|
||||
if untilDepositIndex >= int64(len(c.deposits)) {
|
||||
untilDepositIndex = int64(len(c.deposits) - 1)
|
||||
}
|
||||
|
||||
for i := untilDepositIndex; i >= 0; i-- {
|
||||
// Finding a nil proof means that all proofs up to this deposit have been already pruned.
|
||||
if c.deposits[i].Deposit.Proof == nil {
|
||||
break
|
||||
}
|
||||
c.deposits[i].Deposit.Proof = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrunePendingDeposits removes any deposit which is older than the given deposit merkle tree index.
|
||||
func (c *Cache) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.PrunePendingDeposits")
|
||||
defer span.End()
|
||||
|
||||
if merkleTreeIndex == 0 {
|
||||
log.Debug("Ignoring 0 deposit removal")
|
||||
return
|
||||
}
|
||||
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
|
||||
cleanDeposits := make([]*ethpb.DepositContainer, 0, len(c.pendingDeposits))
|
||||
for _, dp := range c.pendingDeposits {
|
||||
if dp.Index >= merkleTreeIndex {
|
||||
cleanDeposits = append(cleanDeposits, dp)
|
||||
}
|
||||
}
|
||||
|
||||
c.pendingDeposits = cleanDeposits
|
||||
pendingDepositsCount.Set(float64(len(c.pendingDeposits)))
|
||||
}
|
||||
|
||||
// InsertPendingDeposit into the database. If deposit or block number are nil
|
||||
// then this method does nothing.
|
||||
func (c *Cache) InsertPendingDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.InsertPendingDeposit")
|
||||
defer span.End()
|
||||
if d == nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"block": blockNum,
|
||||
"deposit": d,
|
||||
}).Debug("Ignoring nil deposit insertion")
|
||||
return
|
||||
}
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
c.pendingDeposits = append(c.pendingDeposits,
|
||||
ðpb.DepositContainer{Deposit: d, Eth1BlockHeight: blockNum, Index: index, DepositRoot: depositRoot[:]})
|
||||
pendingDepositsCount.Set(float64(len(c.pendingDeposits)))
|
||||
span.AddAttributes(trace.Int64Attribute("count", int64(len(c.pendingDeposits))))
|
||||
}
|
||||
|
||||
// Deposits returns the cached internal deposit tree.
|
||||
func (fd *finalizedDepositsContainer) Deposits() cache.MerkleTree {
|
||||
return fd.depositTree
|
||||
}
|
||||
|
||||
// MerkleTrieIndex represents the last finalized index in
|
||||
// the finalized deposit container.
|
||||
func (fd *finalizedDepositsContainer) MerkleTrieIndex() int64 {
|
||||
return fd.merkleTrieIndex
|
||||
}
|
||||
|
||||
func toFinalizedDepositsContainer(deposits *DepositTree, index int64) finalizedDepositsContainer {
|
||||
return finalizedDepositsContainer{
|
||||
depositTree: deposits,
|
||||
merkleTrieIndex: index,
|
||||
}
|
||||
}
|
||||
|
||||
// PendingDeposits returns a list of deposits until the given block number
|
||||
// (inclusive). If no block is specified then this method returns all pending
|
||||
// deposits.
|
||||
func (c *Cache) PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.PendingDeposits")
|
||||
defer span.End()
|
||||
|
||||
depositCntrs := c.PendingContainers(ctx, untilBlk)
|
||||
|
||||
deposits := make([]*ethpb.Deposit, 0, len(depositCntrs))
|
||||
for _, dep := range depositCntrs {
|
||||
deposits = append(deposits, dep.Deposit)
|
||||
}
|
||||
|
||||
return deposits
|
||||
}
|
||||
|
||||
// PendingContainers returns a list of deposit containers until the given block number
|
||||
// (inclusive).
|
||||
func (c *Cache) PendingContainers(ctx context.Context, untilBlk *big.Int) []*ethpb.DepositContainer {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.PendingContainers")
|
||||
defer span.End()
|
||||
c.depositsLock.RLock()
|
||||
defer c.depositsLock.RUnlock()
|
||||
|
||||
depositCntrs := make([]*ethpb.DepositContainer, 0, len(c.pendingDeposits))
|
||||
for _, ctnr := range c.pendingDeposits {
|
||||
if untilBlk == nil || untilBlk.Uint64() >= ctnr.Eth1BlockHeight {
|
||||
depositCntrs = append(depositCntrs, ctnr)
|
||||
}
|
||||
}
|
||||
// Sort the deposits by Merkle index.
|
||||
sort.SliceStable(depositCntrs, func(i, j int) bool {
|
||||
return depositCntrs[i].Index < depositCntrs[j].Index
|
||||
})
|
||||
|
||||
span.AddAttributes(trace.Int64Attribute("count", int64(len(depositCntrs))))
|
||||
|
||||
return depositCntrs
|
||||
}
|
||||
134
beacon-chain/cache/depositsnapshot/deposit_inserter.go
vendored
Normal file
134
beacon-chain/cache/depositsnapshot/deposit_inserter.go
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
historicalDepositsCount = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Name: "beacondb_all_deposits_eip4881",
|
||||
Help: "The number of total deposits in memory",
|
||||
})
|
||||
log = logrus.WithField("prefix", "cache")
|
||||
)
|
||||
|
||||
// InsertDeposit into the database. If deposit or block number are nil
|
||||
// then this method does nothing.
|
||||
func (c *Cache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.InsertDeposit")
|
||||
defer span.End()
|
||||
if d == nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"block": blockNum,
|
||||
"deposit": d,
|
||||
"index": index,
|
||||
"deposit root": hex.EncodeToString(depositRoot[:]),
|
||||
}).Warn("Ignoring nil deposit insertion")
|
||||
return errors.New("nil deposit inserted into the cache")
|
||||
}
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
|
||||
if int(index) != len(c.deposits) {
|
||||
return errors.Errorf("wanted deposit with index %d to be inserted but received %d", len(c.deposits), index)
|
||||
}
|
||||
// Keep the slice sorted on insertion in order to avoid costly sorting on retrieval.
|
||||
heightIdx := sort.Search(len(c.deposits), func(i int) bool { return c.deposits[i].Index >= index })
|
||||
depCtr := ðpb.DepositContainer{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}
|
||||
newDeposits := append(
|
||||
[]*ethpb.DepositContainer{depCtr},
|
||||
c.deposits[heightIdx:]...)
|
||||
c.deposits = append(c.deposits[:heightIdx], newDeposits...)
|
||||
// Append the deposit to our map, in the event no deposits
|
||||
// exist for the pubkey , it is simply added to the map.
|
||||
pubkey := bytesutil.ToBytes48(d.Data.PublicKey)
|
||||
c.depositsByKey[pubkey] = append(c.depositsByKey[pubkey], depCtr)
|
||||
historicalDepositsCount.Inc()
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertDepositContainers inserts a set of deposit containers into our deposit cache.
|
||||
func (c *Cache) InsertDepositContainers(ctx context.Context, ctrs []*ethpb.DepositContainer) {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.InsertDepositContainers")
|
||||
defer span.End()
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
|
||||
// Initialize slice if nil object provided.
|
||||
if ctrs == nil {
|
||||
ctrs = make([]*ethpb.DepositContainer, 0)
|
||||
}
|
||||
sort.SliceStable(ctrs, func(i int, j int) bool { return ctrs[i].Index < ctrs[j].Index })
|
||||
c.deposits = ctrs
|
||||
for _, ctr := range ctrs {
|
||||
// Use a new value, as the reference
|
||||
// changes in the next iteration.
|
||||
newPtr := ctr
|
||||
pKey := bytesutil.ToBytes48(newPtr.Deposit.Data.PublicKey)
|
||||
c.depositsByKey[pKey] = append(c.depositsByKey[pKey], newPtr)
|
||||
}
|
||||
historicalDepositsCount.Add(float64(len(ctrs)))
|
||||
}
|
||||
|
||||
// InsertFinalizedDeposits inserts deposits up to eth1DepositIndex (inclusive) into the finalized deposits cache.
|
||||
func (c *Cache) InsertFinalizedDeposits(ctx context.Context, eth1DepositIndex int64,
|
||||
executionHash common.Hash, executionNumber uint64) error {
|
||||
ctx, span := trace.StartSpan(ctx, "Cache.InsertFinalizedDeposits")
|
||||
defer span.End()
|
||||
c.depositsLock.Lock()
|
||||
defer c.depositsLock.Unlock()
|
||||
|
||||
depositTrie := c.finalizedDeposits.depositTree
|
||||
insertIndex := int(c.finalizedDeposits.MerkleTrieIndex() + 1)
|
||||
|
||||
// Don't insert into finalized trie if there is no deposit to
|
||||
// insert.
|
||||
if len(c.deposits) == 0 {
|
||||
return nil
|
||||
}
|
||||
// In the event we have less deposits than we need to
|
||||
// finalize we finalize till the index on which we do have it.
|
||||
if len(c.deposits) <= int(eth1DepositIndex) {
|
||||
eth1DepositIndex = int64(len(c.deposits)) - 1
|
||||
}
|
||||
// If we finalize to some lower deposit index, we
|
||||
// ignore it.
|
||||
if int(eth1DepositIndex) < insertIndex {
|
||||
return nil
|
||||
}
|
||||
currIdx := int64(depositTrie.depositCount) - 1
|
||||
|
||||
// Insert deposits into deposit trie.
|
||||
for _, ctr := range c.deposits {
|
||||
if ctr.Index > currIdx && ctr.Index <= eth1DepositIndex {
|
||||
rt, err := ctr.Deposit.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := depositTrie.Insert(rt[:], int(ctr.Index)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := depositTrie.Finalize(eth1DepositIndex, executionHash, executionNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.finalizedDeposits = finalizedDepositsContainer{
|
||||
depositTree: depositTrie,
|
||||
merkleTrieIndex: eth1DepositIndex,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
138
beacon-chain/cache/depositsnapshot/deposit_tree.go
vendored
138
beacon-chain/cache/depositsnapshot/deposit_tree.go
vendored
@@ -4,12 +4,14 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/math"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
|
||||
protodb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -17,12 +19,10 @@ var (
|
||||
ErrEmptyExecutionBlock = errors.New("empty execution block")
|
||||
// ErrInvalidSnapshotRoot occurs when the snapshot root does not match the calculated root.
|
||||
ErrInvalidSnapshotRoot = errors.New("snapshot root is invalid")
|
||||
// ErrInvalidMixInLength occurs when the value for mix in length is 0.
|
||||
ErrInvalidMixInLength = errors.New("mixInLength should be greater than 0")
|
||||
// ErrInvalidDepositCount occurs when the value for mix in length is 0.
|
||||
ErrInvalidDepositCount = errors.New("deposit count should be greater than 0")
|
||||
// ErrInvalidIndex occurs when the index is less than the number of finalized deposits.
|
||||
ErrInvalidIndex = errors.New("index should be greater than finalizedDeposits - 1")
|
||||
// ErrNoDeposits occurs when the number of deposits is 0.
|
||||
ErrNoDeposits = errors.New("number of deposits should be greater than 0")
|
||||
// ErrTooManyDeposits occurs when the number of deposits exceeds the capacity of the tree.
|
||||
ErrTooManyDeposits = errors.New("number of deposits should not be greater than the capacity of the tree")
|
||||
)
|
||||
@@ -30,7 +30,7 @@ var (
|
||||
// DepositTree is the Merkle tree representation of deposits.
|
||||
type DepositTree struct {
|
||||
tree MerkleTreeNode
|
||||
mixInLength uint64 // number of deposits in the tree, reference implementation calls this mix_in_length.
|
||||
depositCount uint64 // number of deposits in the tree, reference implementation calls this mix_in_length.
|
||||
finalizedExecutionBlock executionBlock
|
||||
}
|
||||
|
||||
@@ -39,82 +39,67 @@ type executionBlock struct {
|
||||
Depth uint64
|
||||
}
|
||||
|
||||
// New creates an empty deposit tree.
|
||||
//
|
||||
//nolint:unused
|
||||
func New() *DepositTree {
|
||||
// NewDepositTree creates an empty deposit tree.
|
||||
func NewDepositTree() *DepositTree {
|
||||
var leaves [][32]byte
|
||||
merkle := create(leaves, DepositContractDepth)
|
||||
return &DepositTree{
|
||||
tree: merkle,
|
||||
mixInLength: 0,
|
||||
depositCount: 0,
|
||||
finalizedExecutionBlock: executionBlock{},
|
||||
}
|
||||
}
|
||||
|
||||
// getSnapshot returns a deposit tree snapshot.
|
||||
//
|
||||
//nolint:unused
|
||||
func (d *DepositTree) getSnapshot() (DepositTreeSnapshot, error) {
|
||||
if d.finalizedExecutionBlock == (executionBlock{}) {
|
||||
return DepositTreeSnapshot{}, ErrEmptyExecutionBlock
|
||||
}
|
||||
// GetSnapshot returns a deposit tree snapshot.
|
||||
func (d *DepositTree) GetSnapshot() (DepositTreeSnapshot, error) {
|
||||
var finalized [][32]byte
|
||||
depositCount, finalized := d.tree.GetFinalized(finalized)
|
||||
return fromTreeParts(finalized, depositCount, d.finalizedExecutionBlock)
|
||||
}
|
||||
|
||||
// fromSnapshot returns a deposit tree from a deposit tree snapshot.
|
||||
//
|
||||
//nolint:unused
|
||||
func fromSnapshot(snapshot DepositTreeSnapshot) (DepositTree, error) {
|
||||
func fromSnapshot(snapshot DepositTreeSnapshot) (*DepositTree, error) {
|
||||
root, err := snapshot.CalculateRoot()
|
||||
if err != nil {
|
||||
return DepositTree{}, err
|
||||
return nil, err
|
||||
}
|
||||
if snapshot.depositRoot != root {
|
||||
return DepositTree{}, ErrInvalidSnapshotRoot
|
||||
return nil, ErrInvalidSnapshotRoot
|
||||
}
|
||||
if snapshot.depositCount >= math.PowerOf2(uint64(DepositContractDepth)) {
|
||||
return DepositTree{}, ErrTooManyDeposits
|
||||
return nil, ErrTooManyDeposits
|
||||
}
|
||||
tree, err := fromSnapshotParts(snapshot.finalized, snapshot.depositCount, DepositContractDepth)
|
||||
if err != nil {
|
||||
return DepositTree{}, err
|
||||
return nil, err
|
||||
}
|
||||
if snapshot.depositCount == 0 {
|
||||
return DepositTree{}, ErrNoDeposits
|
||||
}
|
||||
return DepositTree{
|
||||
return &DepositTree{
|
||||
tree: tree,
|
||||
mixInLength: snapshot.depositCount,
|
||||
depositCount: snapshot.depositCount,
|
||||
finalizedExecutionBlock: snapshot.executionBlock,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// finalize marks a deposit as finalized.
|
||||
//
|
||||
//nolint:unused
|
||||
func (d *DepositTree) finalize(eth1data *eth.Eth1Data, executionBlockHeight uint64) error {
|
||||
// Finalize marks a deposit as finalized.
|
||||
func (d *DepositTree) Finalize(eth1DepositIndex int64, executionHash common.Hash, executionNumber uint64) error {
|
||||
var blockHash [32]byte
|
||||
copy(blockHash[:], eth1data.BlockHash)
|
||||
copy(blockHash[:], executionHash[:])
|
||||
d.finalizedExecutionBlock = executionBlock{
|
||||
Hash: blockHash,
|
||||
Depth: executionBlockHeight,
|
||||
Depth: executionNumber,
|
||||
}
|
||||
_, err := d.tree.Finalize(eth1data.DepositCount, DepositContractDepth)
|
||||
depositCount := uint64(eth1DepositIndex + 1)
|
||||
_, err := d.tree.Finalize(depositCount, DepositContractDepth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getProof returns the Deposit tree proof.
|
||||
//
|
||||
//nolint:unused
|
||||
// getProof returns the deposit tree proof.
|
||||
func (d *DepositTree) getProof(index uint64) ([32]byte, [][32]byte, error) {
|
||||
if d.mixInLength <= 0 {
|
||||
return [32]byte{}, nil, ErrInvalidMixInLength
|
||||
if d.depositCount <= 0 {
|
||||
return [32]byte{}, nil, ErrInvalidDepositCount
|
||||
}
|
||||
finalizedDeposits, _ := d.tree.GetFinalized([][32]byte{})
|
||||
if finalizedDeposits != 0 {
|
||||
@@ -125,28 +110,81 @@ func (d *DepositTree) getProof(index uint64) ([32]byte, [][32]byte, error) {
|
||||
}
|
||||
leaf, proof := generateProof(d.tree, index, DepositContractDepth)
|
||||
var mixInLength [32]byte
|
||||
copy(mixInLength[:], bytesutil.Uint64ToBytesLittleEndian32(d.mixInLength))
|
||||
copy(mixInLength[:], bytesutil.Uint64ToBytesLittleEndian32(d.depositCount))
|
||||
proof = append(proof, mixInLength)
|
||||
return leaf, proof, nil
|
||||
}
|
||||
|
||||
// getRoot returns the root of the deposit tree.
|
||||
//
|
||||
//nolint:unused
|
||||
func (d *DepositTree) getRoot() [32]byte {
|
||||
var enc [32]byte
|
||||
binary.LittleEndian.PutUint64(enc[:], d.depositCount)
|
||||
|
||||
root := d.tree.GetRoot()
|
||||
return sha256.Sum256(append(root[:], bytesutil.Uint64ToBytesLittleEndian32(d.mixInLength)...))
|
||||
return hash.Hash(append(root[:], enc[:]...))
|
||||
}
|
||||
|
||||
// pushLeaf adds a new leaf to the tree.
|
||||
//
|
||||
//nolint:unused
|
||||
func (d *DepositTree) pushLeaf(leaf [32]byte) error {
|
||||
var err error
|
||||
d.tree, err = d.tree.PushLeaf(leaf, DepositContractDepth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.mixInLength++
|
||||
d.depositCount++
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert is defined as part of MerkleTree interface and adds a new leaf to the tree.
|
||||
func (d *DepositTree) Insert(item []byte, _ int) error {
|
||||
var leaf [32]byte
|
||||
copy(leaf[:], item[:32])
|
||||
return d.pushLeaf(leaf)
|
||||
}
|
||||
|
||||
// HashTreeRoot is defined as part of MerkleTree interface and calculates the hash tree root.
|
||||
func (d *DepositTree) HashTreeRoot() ([32]byte, error) {
|
||||
root := d.getRoot()
|
||||
if root == [32]byte{} {
|
||||
return [32]byte{}, errors.New("could not retrieve hash tree root")
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// NumOfItems is defined as part of MerkleTree interface and returns the number of deposits in the tree.
|
||||
func (d *DepositTree) NumOfItems() int {
|
||||
return int(d.depositCount)
|
||||
}
|
||||
|
||||
// MerkleProof is defined as part of MerkleTree interface and generates a merkle proof.
|
||||
func (d *DepositTree) MerkleProof(index int) ([][]byte, error) {
|
||||
_, proof, err := d.getProof(uint64(index))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
byteSlices := make([][]byte, len(proof))
|
||||
for i, p := range proof {
|
||||
copied := p
|
||||
byteSlices[i] = copied[:]
|
||||
}
|
||||
return byteSlices, nil
|
||||
}
|
||||
|
||||
// Copy performs a deep copy of the tree.
|
||||
func (d *DepositTree) Copy() (*DepositTree, error) {
|
||||
snapshot, err := d.GetSnapshot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromSnapshot(snapshot)
|
||||
}
|
||||
|
||||
// ToProto returns a proto object of the deposit snapshot of
|
||||
// the tree.
|
||||
func (d *DepositTree) ToProto() (*protodb.DepositSnapshot, error) {
|
||||
snapshot, err := d.GetSnapshot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snapshot.ToProto(), nil
|
||||
}
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
protodb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrZeroIndex occurs when the value of index is 0.
|
||||
ErrZeroIndex = errors.New("index should be greater than 0")
|
||||
)
|
||||
|
||||
// DepositTreeSnapshot represents the data used to create a
|
||||
// deposit tree given a snapshot.
|
||||
//
|
||||
//nolint:unused
|
||||
// DepositTreeSnapshot represents the data used to create a deposit tree given a snapshot.
|
||||
type DepositTreeSnapshot struct {
|
||||
finalized [][32]byte
|
||||
depositRoot [32]byte
|
||||
@@ -27,29 +19,27 @@ type DepositTreeSnapshot struct {
|
||||
func (ds *DepositTreeSnapshot) CalculateRoot() ([32]byte, error) {
|
||||
size := ds.depositCount
|
||||
index := len(ds.finalized)
|
||||
root := Zerohashes[0]
|
||||
root := trie.ZeroHashes[0]
|
||||
for i := 0; i < DepositContractDepth; i++ {
|
||||
if (size & 1) == 1 {
|
||||
if index == 0 {
|
||||
return [32]byte{}, ErrZeroIndex
|
||||
break
|
||||
}
|
||||
index--
|
||||
root = sha256.Sum256(append(ds.finalized[index][:], root[:]...))
|
||||
root = hash.Hash(append(ds.finalized[index][:], root[:]...))
|
||||
} else {
|
||||
root = sha256.Sum256(append(root[:], Zerohashes[i][:]...))
|
||||
root = hash.Hash(append(root[:], trie.ZeroHashes[i][:]...))
|
||||
}
|
||||
size >>= 1
|
||||
}
|
||||
return sha256.Sum256(append(root[:], bytesutil.Uint64ToBytesLittleEndian32(ds.depositCount)...)), nil
|
||||
return hash.Hash(append(root[:], bytesutil.Uint64ToBytesLittleEndian32(ds.depositCount)...)), nil
|
||||
}
|
||||
|
||||
// fromTreeParts constructs the deposit tree from pre-existing data.
|
||||
//
|
||||
//nolint:unused
|
||||
func fromTreeParts(finalised [][32]byte, depositCount uint64, executionBlock executionBlock) (DepositTreeSnapshot, error) {
|
||||
snapshot := DepositTreeSnapshot{
|
||||
finalized: finalised,
|
||||
depositRoot: Zerohashes[0],
|
||||
depositRoot: trie.ZeroHashes[0],
|
||||
depositCount: depositCount,
|
||||
executionBlock: executionBlock,
|
||||
}
|
||||
@@ -60,3 +50,36 @@ func fromTreeParts(finalised [][32]byte, depositCount uint64, executionBlock exe
|
||||
snapshot.depositRoot = root
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
// ToProto converts the underlying trie into its corresponding proto object.
|
||||
func (ds *DepositTreeSnapshot) ToProto() *protodb.DepositSnapshot {
|
||||
tree := &protodb.DepositSnapshot{
|
||||
Finalized: make([][]byte, len(ds.finalized)),
|
||||
DepositRoot: bytesutil.SafeCopyBytes(ds.depositRoot[:]),
|
||||
DepositCount: ds.depositCount,
|
||||
ExecutionHash: bytesutil.SafeCopyBytes(ds.executionBlock.Hash[:]),
|
||||
ExecutionDepth: ds.executionBlock.Depth,
|
||||
}
|
||||
for i := range ds.finalized {
|
||||
tree.Finalized[i] = bytesutil.SafeCopyBytes(ds.finalized[i][:])
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// DepositTreeFromSnapshotProto generates a deposit tree object from a provided snapshot.
|
||||
func DepositTreeFromSnapshotProto(snapshotProto *protodb.DepositSnapshot) (*DepositTree, error) {
|
||||
finalized := make([][32]byte, len(snapshotProto.Finalized))
|
||||
for i := range snapshotProto.Finalized {
|
||||
finalized[i] = bytesutil.ToBytes32(snapshotProto.Finalized[i])
|
||||
}
|
||||
snapshot := DepositTreeSnapshot{
|
||||
finalized: finalized,
|
||||
depositRoot: bytesutil.ToBytes32(snapshotProto.DepositRoot),
|
||||
depositCount: snapshotProto.DepositCount,
|
||||
executionBlock: executionBlock{
|
||||
Hash: bytesutil.ToBytes32(snapshotProto.ExecutionHash),
|
||||
Depth: snapshotProto.ExecutionDepth,
|
||||
},
|
||||
}
|
||||
return fromSnapshot(snapshot)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package depositsnapshot
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/slice"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/math"
|
||||
)
|
||||
@@ -58,9 +59,8 @@ func create(leaves [][32]byte, depth uint64) MerkleTreeNode {
|
||||
}
|
||||
|
||||
// fromSnapshotParts creates a new Merkle tree from a list of finalized leaves, number of deposits and specified depth.
|
||||
//
|
||||
//nolint:unused
|
||||
func fromSnapshotParts(finalized [][32]byte, deposits uint64, level uint64) (_ MerkleTreeNode, err error) {
|
||||
func fromSnapshotParts(finalized [][32]byte, deposits uint64, level uint64) (MerkleTreeNode, error) {
|
||||
var err error
|
||||
if len(finalized) < 1 || deposits == 0 {
|
||||
return &ZeroNode{
|
||||
depth: level,
|
||||
@@ -96,8 +96,6 @@ func fromSnapshotParts(finalized [][32]byte, deposits uint64, level uint64) (_ M
|
||||
}
|
||||
|
||||
// generateProof returns a merkle proof and root
|
||||
//
|
||||
//nolint:unused
|
||||
func generateProof(tree MerkleTreeNode, index uint64, depth uint64) ([32]byte, [][32]byte) {
|
||||
var proof [][32]byte
|
||||
node := tree
|
||||
@@ -219,7 +217,8 @@ func (n *InnerNode) IsFull() bool {
|
||||
}
|
||||
|
||||
// Finalize marks deposits of the Merkle tree as finalized.
|
||||
func (n *InnerNode) Finalize(depositsToFinalize uint64, depth uint64) (_ MerkleTreeNode, err error) {
|
||||
func (n *InnerNode) Finalize(depositsToFinalize uint64, depth uint64) (MerkleTreeNode, error) {
|
||||
var err error
|
||||
deposits := math.PowerOf2(depth)
|
||||
if deposits <= depositsToFinalize {
|
||||
return &FinalizedNode{deposits, n.GetRoot()}, nil
|
||||
@@ -286,9 +285,9 @@ type ZeroNode struct {
|
||||
// GetRoot returns the root of the Merkle tree.
|
||||
func (z *ZeroNode) GetRoot() [32]byte {
|
||||
if z.depth == DepositContractDepth {
|
||||
return hash.Hash(append(Zerohashes[z.depth-1][:], Zerohashes[z.depth-1][:]...))
|
||||
return hash.Hash(append(trie.ZeroHashes[z.depth-1][:], trie.ZeroHashes[z.depth-1][:]...))
|
||||
}
|
||||
return Zerohashes[z.depth]
|
||||
return trie.ZeroHashes[z.depth]
|
||||
}
|
||||
|
||||
// IsFull returns wh ether there is space left for deposits.
|
||||
@@ -300,7 +299,7 @@ func (_ *ZeroNode) IsFull() bool {
|
||||
|
||||
// Finalize marks deposits of the Merkle tree as finalized.
|
||||
func (_ *ZeroNode) Finalize(depositsToFinalize uint64, depth uint64) (MerkleTreeNode, error) {
|
||||
return nil, nil
|
||||
return &ZeroNode{}, nil
|
||||
}
|
||||
|
||||
// GetFinalized returns a list of hashes of all the finalized nodes and the number of deposits.
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
@@ -60,45 +62,54 @@ func Test_fromSnapshotParts(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
finalized [][32]byte
|
||||
deposits uint64
|
||||
level uint64
|
||||
want MerkleTreeNode
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
finalized: nil,
|
||||
deposits: 0,
|
||||
level: 0,
|
||||
want: &ZeroNode{},
|
||||
},
|
||||
{
|
||||
name: "single finalized node",
|
||||
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
deposits: 1,
|
||||
level: 0,
|
||||
want: &FinalizedNode{
|
||||
depositCount: 1,
|
||||
hash: [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple deposits and 1 Finalized",
|
||||
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 0))},
|
||||
deposits: 2,
|
||||
level: 4,
|
||||
want: &InnerNode{
|
||||
left: &InnerNode{&InnerNode{&FinalizedNode{depositCount: 2, hash: hexString(t, fmt.Sprintf("%064d", 0))}, &ZeroNode{1}}, &ZeroNode{2}},
|
||||
right: &ZeroNode{3},
|
||||
},
|
||||
name: "multiple deposits and multiple Finalized",
|
||||
finalized: [][32]byte{hexString(t, fmt.Sprintf("%064d", 1)), hexString(t, fmt.Sprintf("%064d", 2))},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tree, err := fromSnapshotParts(tt.finalized, tt.deposits, tt.level)
|
||||
require.NoError(t, err)
|
||||
if got := tree; !reflect.DeepEqual(got, tt.want) {
|
||||
require.DeepEqual(t, tt.want, got)
|
||||
test := NewDepositTree()
|
||||
for _, leaf := range tt.finalized {
|
||||
err := test.pushLeaf(leaf)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
got, err := test.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
transformed := make([][]byte, len(tt.finalized))
|
||||
for i := 0; i < len(tt.finalized); i++ {
|
||||
transformed[i] = bytesutil.SafeCopyBytes(tt.finalized[i][:])
|
||||
}
|
||||
generatedTrie, err := trie.GenerateTrieFromItems(transformed, 32)
|
||||
require.NoError(t, err)
|
||||
|
||||
want, err := generatedTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, want, got)
|
||||
|
||||
// Test finalization
|
||||
for i := 0; i < len(tt.finalized); i++ {
|
||||
err = test.Finalize(int64(i), tt.finalized[i], 0)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
sShot, err := test.GetSnapshot()
|
||||
require.NoError(t, err)
|
||||
got, err = sShot.CalculateRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(sShot.finalized))
|
||||
require.Equal(t, want, got)
|
||||
|
||||
// Build from the snapshot once more
|
||||
recovered, err := fromSnapshot(sShot)
|
||||
require.NoError(t, err)
|
||||
got, err = recovered.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -125,7 +136,7 @@ func Test_generateProof(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
tree := New()
|
||||
tree := NewDepositTree()
|
||||
for _, c := range testCases[:tt.leaves] {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
93
beacon-chain/cache/depositsnapshot/spec_test.go
vendored
93
beacon-chain/cache/depositsnapshot/spec_test.go
vendored
@@ -1,16 +1,18 @@
|
||||
package depositsnapshot
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/bazelbuild/rules_go/go/tools/bazel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@@ -176,6 +178,9 @@ func readTestCases() ([]testCase, error) {
|
||||
if err != nil {
|
||||
return []testCase{}, err
|
||||
}
|
||||
if len(testCases) == 0 {
|
||||
return nil, errors.New("no test cases found")
|
||||
}
|
||||
return testCases, nil
|
||||
}
|
||||
}
|
||||
@@ -183,11 +188,8 @@ func readTestCases() ([]testCase, error) {
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
tcs, err := readTestCases()
|
||||
_, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, tc := range tcs {
|
||||
t.Log(tc)
|
||||
}
|
||||
}
|
||||
|
||||
func hexStringToByteArray(s string) (b [32]byte, err error) {
|
||||
@@ -222,9 +224,9 @@ func merkleRootFromBranch(leaf [32]byte, branch [][32]byte, index uint64) [32]by
|
||||
for i, l := range branch {
|
||||
ithBit := (index >> i) & 0x1
|
||||
if ithBit == 1 {
|
||||
root = sha256.Sum256(append(l[:], root[:]...))
|
||||
root = hash.Hash(append(l[:], root[:]...))
|
||||
} else {
|
||||
root = sha256.Sum256(append(root[:], l[:]...))
|
||||
root = hash.Hash(append(root[:], l[:]...))
|
||||
}
|
||||
}
|
||||
return root
|
||||
@@ -250,11 +252,11 @@ func cloneFromSnapshot(t *testing.T, snapshot DepositTreeSnapshot, testCases []t
|
||||
err = cp.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
return &cp
|
||||
return cp
|
||||
}
|
||||
|
||||
func TestDepositCases(t *testing.T) {
|
||||
tree := New()
|
||||
tree := NewDepositTree()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases {
|
||||
@@ -263,8 +265,35 @@ func TestDepositCases(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
DepositDataRoot [32]byte
|
||||
}
|
||||
|
||||
func TestRootEquivalence(t *testing.T) {
|
||||
var err error
|
||||
tree := NewDepositTree()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
|
||||
transformed := make([][]byte, len(testCases[:128]))
|
||||
for i, c := range testCases[:128] {
|
||||
err = tree.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
transformed[i] = bytesutil.SafeCopyBytes(c.DepositDataRoot[:])
|
||||
}
|
||||
originalRoot, err := tree.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
generatedTrie, err := trie.GenerateTrieFromItems(transformed, 32)
|
||||
require.NoError(t, err)
|
||||
|
||||
rootA, err := generatedTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, rootA, originalRoot)
|
||||
}
|
||||
|
||||
func TestFinalization(t *testing.T) {
|
||||
tree := New()
|
||||
tree := NewDepositTree()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases[:128] {
|
||||
@@ -273,15 +302,11 @@ func TestFinalization(t *testing.T) {
|
||||
}
|
||||
originalRoot := tree.getRoot()
|
||||
require.DeepEqual(t, testCases[127].Eth1Data.DepositRoot, originalRoot)
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: testCases[100].Eth1Data.DepositRoot[:],
|
||||
DepositCount: testCases[100].Eth1Data.DepositCount,
|
||||
BlockHash: testCases[100].Eth1Data.BlockHash[:],
|
||||
}, testCases[100].BlockHeight)
|
||||
err = tree.Finalize(int64(testCases[100].Eth1Data.DepositCount-1), testCases[100].Eth1Data.BlockHash, testCases[100].BlockHeight)
|
||||
require.NoError(t, err)
|
||||
// ensure finalization doesn't change root
|
||||
require.Equal(t, tree.getRoot(), originalRoot)
|
||||
snapshotData, err := tree.getSnapshot()
|
||||
snapshotData, err := tree.GetSnapshot()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, testCases[100].Snapshot.DepositTreeSnapshot, snapshotData)
|
||||
// create a copy of the tree from a snapshot by replaying
|
||||
@@ -290,20 +315,16 @@ func TestFinalization(t *testing.T) {
|
||||
// ensure original and copy have the same root
|
||||
require.Equal(t, tree.getRoot(), cp.getRoot())
|
||||
// finalize original again to check double finalization
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: testCases[105].Eth1Data.DepositRoot[:],
|
||||
DepositCount: testCases[105].Eth1Data.DepositCount,
|
||||
BlockHash: testCases[105].Eth1Data.BlockHash[:],
|
||||
}, testCases[105].BlockHeight)
|
||||
err = tree.Finalize(int64(testCases[105].Eth1Data.DepositCount-1), testCases[105].Eth1Data.BlockHash, testCases[105].BlockHeight)
|
||||
require.NoError(t, err)
|
||||
// root should still be the same
|
||||
require.Equal(t, originalRoot, tree.getRoot())
|
||||
// create a copy of the tree by taking a snapshot again
|
||||
snapshotData, err = tree.getSnapshot()
|
||||
snapshotData, err = tree.GetSnapshot()
|
||||
require.NoError(t, err)
|
||||
cp = cloneFromSnapshot(t, snapshotData, testCases[106:128])
|
||||
// create a copy of the tree by replaying ALL deposits from nothing
|
||||
fullTreeCopy := New()
|
||||
fullTreeCopy := NewDepositTree()
|
||||
for _, c := range testCases[:128] {
|
||||
err = fullTreeCopy.pushLeaf(c.DepositDataRoot)
|
||||
require.NoError(t, err)
|
||||
@@ -315,7 +336,7 @@ func TestFinalization(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSnapshotCases(t *testing.T) {
|
||||
tree := New()
|
||||
tree := NewDepositTree()
|
||||
testCases, err := readTestCases()
|
||||
require.NoError(t, err)
|
||||
for _, c := range testCases {
|
||||
@@ -323,33 +344,29 @@ func TestSnapshotCases(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
for _, c := range testCases {
|
||||
err = tree.finalize(ð.Eth1Data{
|
||||
DepositRoot: c.Eth1Data.DepositRoot[:],
|
||||
DepositCount: c.Eth1Data.DepositCount,
|
||||
BlockHash: c.Eth1Data.BlockHash[:],
|
||||
}, c.BlockHeight)
|
||||
err = tree.Finalize(int64(c.Eth1Data.DepositCount-1), c.Eth1Data.BlockHash, c.BlockHeight)
|
||||
require.NoError(t, err)
|
||||
s, err := tree.getSnapshot()
|
||||
s, err := tree.GetSnapshot()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, c.Snapshot.DepositTreeSnapshot, s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyTreeSnapshot(t *testing.T) {
|
||||
_, err := New().getSnapshot()
|
||||
require.ErrorContains(t, "empty execution block", err)
|
||||
}
|
||||
|
||||
func TestInvalidSnapshot(t *testing.T) {
|
||||
invalidSnapshot := DepositTreeSnapshot{
|
||||
finalized: nil,
|
||||
depositRoot: Zerohashes[0],
|
||||
depositRoot: trie.ZeroHashes[0],
|
||||
depositCount: 0,
|
||||
executionBlock: executionBlock{
|
||||
Hash: Zerohashes[0],
|
||||
Hash: trie.ZeroHashes[0],
|
||||
Depth: 0,
|
||||
},
|
||||
}
|
||||
_, err := fromSnapshot(invalidSnapshot)
|
||||
require.ErrorContains(t, "snapshot root is invalid", err)
|
||||
}
|
||||
|
||||
func TestEmptyTree(t *testing.T) {
|
||||
tree := NewDepositTree()
|
||||
require.Equal(t, fmt.Sprintf("%x", tree.getRoot()), "d70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e")
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
// Code generated by gen_zerohashes. DO NOT EDIT.
|
||||
package depositsnapshot
|
||||
|
||||
var Zerohashes = [][32]byte{
|
||||
// 0000000000000000000000000000000000000000000000000000000000000000
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
// f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b
|
||||
{245, 165, 253, 66, 209, 106, 32, 48, 39, 152, 239, 110, 211, 9, 151, 155, 67, 0, 61, 35, 32, 217, 240, 232, 234, 152, 49, 169, 39, 89, 251, 75},
|
||||
// db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71
|
||||
{219, 86, 17, 78, 0, 253, 212, 193, 248, 92, 137, 43, 243, 90, 201, 168, 146, 137, 170, 236, 177, 235, 208, 169, 108, 222, 96, 106, 116, 139, 93, 113},
|
||||
// c78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c
|
||||
{199, 128, 9, 253, 240, 127, 197, 106, 17, 241, 34, 55, 6, 88, 163, 83, 170, 165, 66, 237, 99, 228, 76, 75, 193, 95, 244, 205, 16, 90, 179, 60},
|
||||
// 536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c
|
||||
{83, 109, 152, 131, 127, 45, 209, 101, 165, 93, 94, 234, 233, 20, 133, 149, 68, 114, 213, 111, 36, 109, 242, 86, 191, 60, 174, 25, 53, 42, 18, 60},
|
||||
// 9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30
|
||||
{158, 253, 224, 82, 170, 21, 66, 159, 174, 5, 186, 212, 208, 177, 215, 198, 77, 166, 77, 3, 215, 161, 133, 74, 88, 140, 44, 184, 67, 12, 13, 48},
|
||||
// d88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1
|
||||
{216, 141, 223, 238, 212, 0, 168, 117, 85, 150, 178, 25, 66, 193, 73, 126, 17, 76, 48, 46, 97, 24, 41, 15, 145, 230, 119, 41, 118, 4, 31, 161},
|
||||
// 87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c
|
||||
{135, 235, 13, 219, 165, 126, 53, 246, 210, 134, 103, 56, 2, 164, 175, 89, 117, 226, 37, 6, 199, 207, 76, 100, 187, 107, 229, 238, 17, 82, 127, 44},
|
||||
// 26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193
|
||||
{38, 132, 100, 118, 253, 95, 197, 74, 93, 67, 56, 81, 103, 201, 81, 68, 242, 100, 63, 83, 60, 200, 91, 185, 209, 107, 120, 47, 141, 125, 177, 147},
|
||||
// 506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1
|
||||
{80, 109, 134, 88, 45, 37, 36, 5, 184, 64, 1, 135, 146, 202, 210, 191, 18, 89, 241, 239, 90, 165, 248, 135, 225, 60, 178, 240, 9, 79, 81, 225},
|
||||
// ffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b
|
||||
{255, 255, 10, 215, 230, 89, 119, 47, 149, 52, 193, 149, 200, 21, 239, 196, 1, 78, 241, 225, 218, 237, 68, 4, 192, 99, 133, 209, 17, 146, 233, 43},
|
||||
// 6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220
|
||||
{108, 240, 65, 39, 219, 5, 68, 28, 216, 51, 16, 122, 82, 190, 133, 40, 104, 137, 14, 67, 23, 230, 160, 42, 180, 118, 131, 170, 117, 150, 66, 32},
|
||||
// b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f
|
||||
{183, 208, 95, 135, 95, 20, 0, 39, 239, 81, 24, 162, 36, 123, 187, 132, 206, 143, 47, 15, 17, 35, 98, 48, 133, 218, 247, 150, 12, 50, 159, 95},
|
||||
// df6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e
|
||||
{223, 106, 245, 245, 187, 219, 107, 233, 239, 138, 166, 24, 228, 191, 128, 115, 150, 8, 103, 23, 30, 41, 103, 111, 139, 40, 77, 234, 106, 8, 168, 94},
|
||||
// b58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784
|
||||
{181, 141, 144, 15, 94, 24, 46, 60, 80, 239, 116, 150, 158, 161, 108, 119, 38, 197, 73, 117, 124, 194, 53, 35, 195, 105, 88, 125, 167, 41, 55, 132},
|
||||
// d49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb
|
||||
{212, 154, 117, 2, 255, 207, 176, 52, 11, 29, 120, 133, 104, 133, 0, 202, 48, 129, 97, 167, 249, 107, 98, 223, 157, 8, 59, 113, 252, 200, 242, 187},
|
||||
// 8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb
|
||||
{143, 230, 177, 104, 146, 86, 192, 211, 133, 244, 47, 91, 190, 32, 39, 162, 44, 25, 150, 225, 16, 186, 151, 193, 113, 211, 229, 148, 141, 233, 43, 235},
|
||||
// 8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab
|
||||
{141, 13, 99, 195, 158, 186, 222, 133, 9, 224, 174, 60, 156, 56, 118, 251, 95, 161, 18, 190, 24, 249, 5, 236, 172, 254, 203, 146, 5, 118, 3, 171},
|
||||
// 95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4
|
||||
{149, 238, 200, 178, 229, 65, 202, 212, 233, 29, 227, 131, 133, 242, 224, 70, 97, 159, 84, 73, 108, 35, 130, 203, 108, 172, 213, 185, 140, 38, 245, 164},
|
||||
// f893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f
|
||||
{248, 147, 233, 8, 145, 119, 117, 182, 43, 255, 35, 41, 77, 187, 227, 161, 205, 142, 108, 193, 195, 91, 72, 1, 136, 123, 100, 106, 111, 129, 241, 127},
|
||||
// cddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa
|
||||
{205, 219, 167, 181, 146, 227, 19, 51, 147, 193, 97, 148, 250, 199, 67, 26, 191, 47, 84, 133, 237, 113, 29, 178, 130, 24, 60, 129, 158, 8, 235, 170},
|
||||
// 8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c
|
||||
{138, 141, 127, 227, 175, 140, 170, 8, 90, 118, 57, 168, 50, 0, 20, 87, 223, 185, 18, 138, 128, 97, 20, 42, 208, 51, 86, 41, 255, 35, 255, 156},
|
||||
// feb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167
|
||||
{254, 179, 195, 55, 215, 165, 26, 111, 191, 0, 185, 227, 76, 82, 225, 201, 25, 92, 150, 155, 212, 231, 160, 191, 213, 29, 92, 91, 237, 156, 17, 103},
|
||||
// e71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7
|
||||
{231, 31, 10, 168, 60, 195, 46, 223, 190, 250, 159, 77, 62, 1, 116, 202, 133, 24, 46, 236, 159, 58, 9, 246, 166, 192, 223, 99, 119, 165, 16, 215},
|
||||
// 31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0
|
||||
{49, 32, 111, 168, 10, 80, 187, 106, 190, 41, 8, 80, 88, 241, 98, 18, 33, 42, 96, 238, 200, 240, 73, 254, 203, 146, 216, 200, 224, 168, 75, 192},
|
||||
// 21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544
|
||||
{33, 53, 43, 254, 203, 237, 221, 233, 147, 131, 159, 97, 76, 61, 172, 10, 62, 227, 117, 67, 249, 180, 18, 177, 97, 153, 220, 21, 142, 35, 181, 68},
|
||||
// 619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765
|
||||
{97, 158, 49, 39, 36, 187, 109, 124, 49, 83, 237, 157, 231, 145, 215, 100, 163, 102, 179, 137, 175, 19, 197, 139, 248, 168, 217, 4, 129, 164, 103, 101},
|
||||
// 7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4
|
||||
{124, 221, 41, 134, 38, 130, 80, 98, 141, 12, 16, 227, 133, 197, 140, 97, 145, 230, 251, 224, 81, 145, 188, 192, 79, 19, 63, 44, 234, 114, 193, 196},
|
||||
// 848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1
|
||||
{132, 137, 48, 189, 123, 168, 202, 197, 70, 97, 7, 33, 19, 251, 39, 136, 105, 224, 123, 184, 88, 127, 145, 57, 41, 51, 55, 77, 1, 123, 203, 225},
|
||||
// 8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636
|
||||
{136, 105, 255, 44, 34, 178, 140, 193, 5, 16, 217, 133, 50, 146, 128, 51, 40, 190, 79, 176, 232, 4, 149, 232, 187, 141, 39, 31, 91, 136, 150, 54},
|
||||
// b5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c
|
||||
{181, 254, 40, 231, 159, 27, 133, 15, 134, 88, 36, 108, 233, 182, 161, 231, 180, 159, 192, 109, 183, 20, 62, 143, 224, 180, 242, 176, 197, 82, 58, 92},
|
||||
// 985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7
|
||||
{152, 94, 146, 159, 112, 175, 40, 208, 189, 209, 169, 10, 128, 143, 151, 127, 89, 124, 124, 119, 140, 72, 158, 152, 211, 189, 137, 16, 211, 26, 192, 247},
|
||||
}
|
||||
57
beacon-chain/cache/interfaces.go
vendored
Normal file
57
beacon-chain/cache/interfaces.go
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// DepositCache combines the interfaces for retrieving and inserting deposit information.
|
||||
type DepositCache interface {
|
||||
DepositFetcher
|
||||
DepositInserter
|
||||
}
|
||||
|
||||
// DepositFetcher defines a struct which can retrieve deposit information from a store.
|
||||
type DepositFetcher interface {
|
||||
AllDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
|
||||
AllDepositContainers(ctx context.Context) []*ethpb.DepositContainer
|
||||
DepositByPubkey(ctx context.Context, pubKey []byte) (*ethpb.Deposit, *big.Int)
|
||||
DepositsNumberAndRootAtHeight(ctx context.Context, blockHeight *big.Int) (uint64, [32]byte)
|
||||
InsertPendingDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte)
|
||||
PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit
|
||||
PendingContainers(ctx context.Context, untilBlk *big.Int) []*ethpb.DepositContainer
|
||||
PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64)
|
||||
PruneProofs(ctx context.Context, untilDepositIndex int64) error
|
||||
FinalizedFetcher
|
||||
}
|
||||
|
||||
// DepositInserter defines a struct which can insert deposit information from a store.
|
||||
type DepositInserter interface {
|
||||
InsertDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) error
|
||||
InsertDepositContainers(ctx context.Context, ctrs []*ethpb.DepositContainer)
|
||||
InsertFinalizedDeposits(ctx context.Context, eth1DepositIndex int64, executionHash common.Hash, executionNumber uint64) error
|
||||
}
|
||||
|
||||
// FinalizedFetcher is a smaller interface defined to be the bare minimum to satisfy “Service”.
|
||||
// It extends the "DepositFetcher" interface with additional methods for fetching finalized deposits.
|
||||
type FinalizedFetcher interface {
|
||||
FinalizedDeposits(ctx context.Context) (FinalizedDeposits, error)
|
||||
NonFinalizedDeposits(ctx context.Context, lastFinalizedIndex int64, untilBlk *big.Int) []*ethpb.Deposit
|
||||
}
|
||||
|
||||
// FinalizedDeposits defines a method to access a merkle tree containing deposits and their indexes.
|
||||
type FinalizedDeposits interface {
|
||||
Deposits() MerkleTree
|
||||
MerkleTrieIndex() int64
|
||||
}
|
||||
|
||||
// MerkleTree defines methods for constructing and manipulating a merkle tree.
|
||||
type MerkleTree interface {
|
||||
HashTreeRoot() ([32]byte, error)
|
||||
NumOfItems() int
|
||||
Insert(item []byte, index int) error
|
||||
MerkleProof(index int) ([][]byte, error)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/deterministic-genesis",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/execution:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/execution"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
var _ runtime.Service = (*Service)(nil)
|
||||
var _ depositcache.DepositFetcher = (*Service)(nil)
|
||||
var _ cache.FinalizedFetcher = (*Service)(nil)
|
||||
var _ execution.ChainStartFetcher = (*Service)(nil)
|
||||
|
||||
// Service spins up an client interoperability service that handles responsibilities such
|
||||
@@ -34,12 +34,42 @@ type Service struct {
|
||||
chainStartDeposits []*ethpb.Deposit
|
||||
}
|
||||
|
||||
// All of these methods are stubs as they are not used by a node running with deterministic-genesis.
|
||||
|
||||
func (s *Service) AllDepositContainers(ctx context.Context) []*ethpb.DepositContainer {
|
||||
log.Errorf("AllDepositContainers should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) InsertPendingDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) {
|
||||
log.Errorf("InsertPendingDeposit should not be called")
|
||||
}
|
||||
|
||||
func (s *Service) PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit {
|
||||
log.Errorf("PendingDeposits should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) PendingContainers(ctx context.Context, untilBlk *big.Int) []*ethpb.DepositContainer {
|
||||
log.Errorf("PendingContainers should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64) {
|
||||
log.Errorf("PrunePendingDeposits should not be called")
|
||||
}
|
||||
|
||||
func (s *Service) PruneProofs(ctx context.Context, untilDepositIndex int64) error {
|
||||
log.Errorf("PruneProofs should not be called")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Config options for the interop service.
|
||||
type Config struct {
|
||||
GenesisTime uint64
|
||||
NumValidators uint64
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
DepositCache *depositcache.DepositCache
|
||||
DepositCache cache.DepositCache
|
||||
GenesisPath string
|
||||
}
|
||||
|
||||
@@ -148,8 +178,8 @@ func (_ *Service) DepositsNumberAndRootAtHeight(_ context.Context, _ *big.Int) (
|
||||
}
|
||||
|
||||
// FinalizedDeposits mocks out the deposit cache functionality for interop.
|
||||
func (_ *Service) FinalizedDeposits(_ context.Context) *depositcache.FinalizedDeposits {
|
||||
return nil
|
||||
func (_ *Service) FinalizedDeposits(ctx context.Context) (cache.FinalizedDeposits, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NonFinalizedDeposits mocks out the deposit cache functionality for interop.
|
||||
|
||||
@@ -25,7 +25,8 @@ go_library(
|
||||
"//testing/spectest:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/cache/depositsnapshot:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/feed:go_default_library",
|
||||
"//beacon-chain/core/feed/state:go_default_library",
|
||||
|
||||
@@ -13,13 +13,16 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
coreState "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/types"
|
||||
statenative "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
contracts "github.com/prysmaticlabs/prysm/v4/contracts/deposit"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -141,7 +144,6 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog *gethtypes.L
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to determine hashed value of deposit")
|
||||
}
|
||||
|
||||
// Defensive check to validate incoming index.
|
||||
if s.depositTrie.NumOfItems() != int(index) {
|
||||
return errors.Errorf("invalid deposit index received: wanted %d but got %d", s.depositTrie.NumOfItems(), index)
|
||||
@@ -149,7 +151,6 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog *gethtypes.L
|
||||
if err = s.depositTrie.Insert(depositHash[:], int(index)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deposit := ðpb.Deposit{
|
||||
Data: depositData,
|
||||
}
|
||||
@@ -221,6 +222,18 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog *gethtypes.L
|
||||
"merkleTreeIndex": index,
|
||||
}).Info("Invalid deposit registered in deposit contract")
|
||||
}
|
||||
if features.Get().EnableEIP4881 {
|
||||
// We finalize the trie here so that old deposits are not kept around, as they make
|
||||
// deposit tree htr computation expensive.
|
||||
dTrie, ok := s.depositTrie.(*depositsnapshot.DepositTree)
|
||||
if !ok {
|
||||
return errors.Errorf("wrong trie type initialized: %T", dTrie)
|
||||
}
|
||||
if err := dTrie.Finalize(index, depositLog.BlockHash, depositLog.BlockNumber); err != nil {
|
||||
log.WithError(err).Error("Could not finalize trie")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -337,7 +350,7 @@ func (s *Service) processPastLogs(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
if fState != nil && !fState.IsNil() && fState.Eth1DepositIndex() > 0 {
|
||||
s.cfg.depositCache.PrunePendingDeposits(ctx, int64(fState.Eth1DepositIndex())) // lint:ignore uintcast -- Deposit index should not exceed int64 in your lifetime.
|
||||
s.cfg.depositCache.PrunePendingDeposits(ctx, int64(fState.Eth1DepositIndex())) // lint:ignore uintcast -- deposit index should not exceed int64 in your lifetime.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -559,8 +572,27 @@ func (s *Service) savePowchainData(ctx context.Context) error {
|
||||
CurrentEth1Data: s.latestEth1Data,
|
||||
ChainstartData: s.chainStartData,
|
||||
BeaconState: pbState, // I promise not to mutate it!
|
||||
Trie: s.depositTrie.ToProto(),
|
||||
DepositContainers: s.cfg.depositCache.AllDepositContainers(ctx),
|
||||
}
|
||||
if features.Get().EnableEIP4881 {
|
||||
fd, err := s.cfg.depositCache.FinalizedDeposits(ctx)
|
||||
if err != nil {
|
||||
return errors.Errorf("could not get finalized deposit tree: %v", err)
|
||||
}
|
||||
tree, ok := fd.Deposits().(*depositsnapshot.DepositTree)
|
||||
if !ok {
|
||||
return errors.New("deposit tree was not EIP4881 DepositTree")
|
||||
}
|
||||
eth1Data.DepositSnapshot, err = tree.ToProto()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
tree, ok := s.depositTrie.(*trie.SparseMerkleTrie)
|
||||
if !ok {
|
||||
return errors.New("deposit tree was not SparseMerkleTrie")
|
||||
}
|
||||
eth1Data.Trie = tree.ToProto()
|
||||
}
|
||||
return s.cfg.beaconDB.SaveExecutionChainData(ctx, eth1Data)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package execution
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
@@ -62,7 +62,7 @@ func WithDatabase(database db.HeadAccessDatabase) Option {
|
||||
}
|
||||
|
||||
// WithDepositCache for caching deposits.
|
||||
func WithDepositCache(cache *depositcache.DepositCache) Option {
|
||||
func WithDepositCache(cache cache.DepositCache) Option {
|
||||
return func(s *Service) error {
|
||||
s.cfg.depositCache = cache
|
||||
return nil
|
||||
|
||||
@@ -20,7 +20,8 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
contracts "github.com/prysmaticlabs/prysm/v4/contracts/deposit"
|
||||
@@ -119,7 +121,7 @@ func (RPCClientEmpty) CallContext(context.Context, interface{}, string, ...inter
|
||||
type config struct {
|
||||
depositContractAddr common.Address
|
||||
beaconDB db.HeadAccessDatabase
|
||||
depositCache *depositcache.DepositCache
|
||||
depositCache cache.DepositCache
|
||||
stateNotifier statefeed.Notifier
|
||||
stateGen *stategen.State
|
||||
eth1HeaderReqLimit uint64
|
||||
@@ -149,7 +151,7 @@ type Service struct {
|
||||
headerCache *headerCache // cache to store block hash/block height.
|
||||
latestEth1Data *ethpb.LatestETH1Data
|
||||
depositContractCaller *contracts.DepositContractCaller
|
||||
depositTrie *trie.SparseMerkleTrie
|
||||
depositTrie cache.MerkleTree
|
||||
chainStartData *ethpb.ChainStartData
|
||||
lastReceivedMerkleIndex int64 // Keeps track of the last received index to prevent log spam.
|
||||
runError error
|
||||
@@ -160,10 +162,15 @@ type Service struct {
|
||||
func NewService(ctx context.Context, opts ...Option) (*Service, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
_ = cancel // govet fix for lost cancel. Cancel is handled in service.Stop()
|
||||
depositTrie, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, errors.Wrap(err, "could not set up deposit trie")
|
||||
var depositTrie cache.MerkleTree
|
||||
var err error
|
||||
if features.Get().EnableEIP4881 {
|
||||
depositTrie = depositsnapshot.NewDepositTree()
|
||||
} else {
|
||||
depositTrie, err = trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not set up deposit trie")
|
||||
}
|
||||
}
|
||||
genState, err := transition.EmptyGenesisState()
|
||||
if err != nil {
|
||||
@@ -209,7 +216,6 @@ func NewService(ctx context.Context, opts ...Option) (*Service, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to retrieve eth1 data")
|
||||
}
|
||||
|
||||
if err := s.initializeEth1Data(ctx, eth1Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -370,7 +376,8 @@ func (s *Service) initDepositCaches(ctx context.Context, ctrs []*ethpb.DepositCo
|
||||
// to be included (rather than the last one to be processed). This was most likely
|
||||
// done as the state cannot represent signed integers.
|
||||
actualIndex := int64(currIndex) - 1 // lint:ignore uintcast -- deposit index will not exceed int64 in your lifetime.
|
||||
if err = s.cfg.depositCache.InsertFinalizedDeposits(ctx, actualIndex); err != nil {
|
||||
if err = s.cfg.depositCache.InsertFinalizedDeposits(ctx, actualIndex, common.Hash(fState.Eth1Data().BlockHash),
|
||||
0 /* Setting a zero value as we have no access to block height */); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -742,7 +749,17 @@ func (s *Service) initializeEth1Data(ctx context.Context, eth1DataInDB *ethpb.ET
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
s.depositTrie, err = trie.CreateTrieFromProto(eth1DataInDB.Trie)
|
||||
if features.Get().EnableEIP4881 {
|
||||
if eth1DataInDB.DepositSnapshot != nil {
|
||||
s.depositTrie, err = depositsnapshot.DepositTreeFromSnapshotProto(eth1DataInDB.DepositSnapshot)
|
||||
} else {
|
||||
if err := s.migrateOldDepositTree(eth1DataInDB); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.depositTrie, err = trie.CreateTrieFromProto(eth1DataInDB.Trie)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -754,6 +771,24 @@ func (s *Service) initializeEth1Data(ctx context.Context, eth1DataInDB *ethpb.ET
|
||||
}
|
||||
}
|
||||
s.latestEth1Data = eth1DataInDB.CurrentEth1Data
|
||||
if features.Get().EnableEIP4881 {
|
||||
ctrs := eth1DataInDB.DepositContainers
|
||||
// Look at previously finalized index, as we are building off a finalized
|
||||
// snapshot rather than the full trie.
|
||||
lastFinalizedIndex := int64(s.depositTrie.NumOfItems() - 1)
|
||||
// Correctly initialize missing deposits into active trie.
|
||||
for _, c := range ctrs {
|
||||
if c.Index > lastFinalizedIndex {
|
||||
depRoot, err := c.Deposit.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.depositTrie.Insert(depRoot[:], int(c.Index)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numOfItems := s.depositTrie.NumOfItems()
|
||||
s.lastReceivedMerkleIndex = int64(numOfItems - 1)
|
||||
if err := s.initDepositCaches(ctx, eth1DataInDB.DepositContainers); err != nil {
|
||||
@@ -816,9 +851,24 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
|
||||
CurrentEth1Data: s.latestEth1Data,
|
||||
ChainstartData: s.chainStartData,
|
||||
BeaconState: pbState,
|
||||
Trie: s.depositTrie.ToProto(),
|
||||
DepositContainers: s.cfg.depositCache.AllDepositContainers(ctx),
|
||||
}
|
||||
if features.Get().EnableEIP4881 {
|
||||
trie, ok := s.depositTrie.(*depositsnapshot.DepositTree)
|
||||
if !ok {
|
||||
return errors.New("deposit trie was not EIP4881 DepositTree")
|
||||
}
|
||||
eth1Data.DepositSnapshot, err = trie.ToProto()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
trie, ok := s.depositTrie.(*trie.SparseMerkleTrie)
|
||||
if !ok {
|
||||
return errors.New("deposit trie was not SparseMerkleTrie")
|
||||
}
|
||||
eth1Data.Trie = trie.ToProto()
|
||||
}
|
||||
return s.cfg.beaconDB.SaveExecutionChainData(ctx, eth1Data)
|
||||
}
|
||||
return nil
|
||||
@@ -836,3 +886,29 @@ func dedupEndpoints(endpoints []string) []string {
|
||||
}
|
||||
return newEndpoints
|
||||
}
|
||||
|
||||
func (s *Service) migrateOldDepositTree(eth1DataInDB *ethpb.ETH1ChainData) error {
|
||||
oldDepositTrie, err := trie.CreateTrieFromProto(eth1DataInDB.Trie)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDepositTrie := depositsnapshot.NewDepositTree()
|
||||
for i, item := range oldDepositTrie.Items() {
|
||||
if err = newDepositTrie.Insert(item, i); err != nil {
|
||||
return errors.Wrapf(err, "could not insert item at index %d into deposit snapshot tree", i)
|
||||
}
|
||||
}
|
||||
newDepositRoot, err := newDepositTrie.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
depositRoot, err := oldDepositTrie.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newDepositRoot != depositRoot {
|
||||
return errors.Wrapf(err, "mismatched deposit roots, old %#x != new %#x", depositRoot, newDepositRoot)
|
||||
}
|
||||
s.depositTrie = newDepositTrie
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
contracts "github.com/prysmaticlabs/prysm/v4/contracts/deposit"
|
||||
"github.com/prysmaticlabs/prysm/v4/contracts/deposit/mock"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -433,8 +434,9 @@ func TestInitDepositCacheWithFinalization_OK(t *testing.T) {
|
||||
|
||||
s.chainStartData.Chainstarted = true
|
||||
require.NoError(t, s.initDepositCaches(context.Background(), ctrs))
|
||||
fDeposits := s.cfg.depositCache.FinalizedDeposits(ctx)
|
||||
deps := s.cfg.depositCache.NonFinalizedDeposits(context.Background(), fDeposits.MerkleTrieIndex, nil)
|
||||
fDeposits, err := s.cfg.depositCache.FinalizedDeposits(ctx)
|
||||
require.NoError(t, err)
|
||||
deps := s.cfg.depositCache.NonFinalizedDeposits(context.Background(), fDeposits.MerkleTrieIndex(), nil)
|
||||
assert.Equal(t, 0, len(deps))
|
||||
}
|
||||
|
||||
@@ -801,3 +803,50 @@ func (s *slowRPCClient) BatchCall(b []rpc.BatchElem) error {
|
||||
func (s *slowRPCClient) CallContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func TestService_migrateOldDepositTree(t *testing.T) {
|
||||
beaconDB := dbutil.SetupDB(t)
|
||||
cache, err := depositcache.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
srv, endpoint, err := mockExecution.SetupRPCServer()
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
srv.Stop()
|
||||
})
|
||||
s, err := NewService(context.Background(),
|
||||
WithHttpEndpoint(endpoint),
|
||||
WithDatabase(beaconDB),
|
||||
WithDepositCache(cache),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
eth1Data := ðpb.ETH1ChainData{
|
||||
BeaconState: ðpb.BeaconState{
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
DepositCount: 800,
|
||||
},
|
||||
},
|
||||
CurrentEth1Data: ðpb.LatestETH1Data{
|
||||
BlockHeight: 100,
|
||||
},
|
||||
}
|
||||
|
||||
totalDeposits := 1000
|
||||
input := bytesutil.ToBytes32([]byte("foo"))
|
||||
dt, err := trie.NewTrie(32)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := 0; i < totalDeposits; i++ {
|
||||
err := dt.Insert(input[:], i)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
eth1Data.Trie = dt.ToProto()
|
||||
|
||||
err = s.migrateOldDepositTree(eth1Data)
|
||||
require.NoError(t, err)
|
||||
oldDepositTreeRoot, err := dt.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
newDepositTreeRoot, err := s.depositTrie.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, oldDepositTreeRoot, newDepositTreeRoot)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ go_library(
|
||||
"//beacon-chain/builder:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/cache/depositsnapshot:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/db/kv:go_default_library",
|
||||
"//beacon-chain/db/slasherkv:go_default_library",
|
||||
|
||||
@@ -23,6 +23,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/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositsnapshot"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/slasherkv"
|
||||
@@ -94,7 +95,7 @@ type BeaconNode struct {
|
||||
slashingsPool slashings.PoolManager
|
||||
syncCommitteePool synccommittee.Pool
|
||||
blsToExecPool blstoexec.PoolManager
|
||||
depositCache *depositcache.DepositCache
|
||||
depositCache cache.DepositCache
|
||||
proposerIdsCache *cache.ProposerPayloadIDsCache
|
||||
stateFeed *event.Feed
|
||||
blockFeed *event.Feed
|
||||
@@ -406,10 +407,16 @@ func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error {
|
||||
|
||||
b.db = d
|
||||
|
||||
depositCache, err := depositcache.New()
|
||||
var depositCache cache.DepositCache
|
||||
if features.Get().EnableEIP4881 {
|
||||
depositCache, err = depositsnapshot.New()
|
||||
} else {
|
||||
depositCache, err = depositcache.New()
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not create deposit cache")
|
||||
}
|
||||
|
||||
b.depositCache = depositCache
|
||||
|
||||
if b.GenesisInitializer != nil {
|
||||
@@ -781,7 +788,7 @@ func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
}
|
||||
|
||||
genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
|
||||
var depositFetcher depositcache.DepositFetcher
|
||||
var depositFetcher cache.DepositFetcher
|
||||
var chainStartFetcher execution.ChainStartFetcher
|
||||
if genesisValidators > 0 {
|
||||
var interopService *interopcoldstart.Service
|
||||
|
||||
@@ -62,8 +62,13 @@ func wrapValidatorIndicesArray(
|
||||
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"`
|
||||
}
|
||||
|
||||
type phase0PublishBlockRequestJson struct {
|
||||
Phase0Block *SignedBeaconBlockJson `json:"phase0_block"`
|
||||
Message *v1alpha1SignedPhase0Block `json:"phase0_block"`
|
||||
}
|
||||
|
||||
type altairPublishBlockRequestJson struct {
|
||||
@@ -160,42 +165,40 @@ func setInitialPublishBlockPostRequest(endpoint *apimiddleware.Endpoint,
|
||||
func preparePublishedBlock(endpoint *apimiddleware.Endpoint, _ http.ResponseWriter, _ *http.Request) apimiddleware.ErrorJson {
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &phase0PublishBlockRequestJson{
|
||||
Phase0Block: block,
|
||||
endpoint.PostRequest = &phase0PublishBlockRequestJson{
|
||||
Message: &v1alpha1SignedPhase0Block{
|
||||
Block: block.Message,
|
||||
Signature: block.Signature,
|
||||
},
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockAltairJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &altairPublishBlockRequestJson{
|
||||
endpoint.PostRequest = &altairPublishBlockRequestJson{
|
||||
AltairBlock: block,
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockBellatrixJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &bellatrixPublishBlockRequestJson{
|
||||
endpoint.PostRequest = &bellatrixPublishBlockRequestJson{
|
||||
BellatrixBlock: block,
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockCapellaJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &capellaPublishBlockRequestJson{
|
||||
endpoint.PostRequest = &capellaPublishBlockRequestJson{
|
||||
CapellaBlock: block,
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockContentsDenebJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &denebPublishBlockRequestJson{
|
||||
endpoint.PostRequest = &denebPublishBlockRequestJson{
|
||||
DenebContents: block,
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
return apimiddleware.InternalServerError(errors.New("unsupported block type"))
|
||||
@@ -266,11 +269,12 @@ func setInitialPublishBlindedBlockPostRequest(endpoint *apimiddleware.Endpoint,
|
||||
// (which was filled out previously in setInitialPublishBlockPostRequest).
|
||||
func preparePublishedBlindedBlock(endpoint *apimiddleware.Endpoint, _ http.ResponseWriter, _ *http.Request) apimiddleware.ErrorJson {
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockJson); ok {
|
||||
// Prepare post request that can be properly decoded on gRPC side.
|
||||
actualPostReq := &phase0PublishBlockRequestJson{
|
||||
Phase0Block: block,
|
||||
endpoint.PostRequest = &phase0PublishBlockRequestJson{
|
||||
Message: &v1alpha1SignedPhase0Block{
|
||||
Block: block.Message,
|
||||
Signature: block.Signature,
|
||||
},
|
||||
}
|
||||
endpoint.PostRequest = actualPostReq
|
||||
return nil
|
||||
}
|
||||
if block, ok := endpoint.PostRequest.(*SignedBeaconBlockAltairJson); ok {
|
||||
|
||||
@@ -20,7 +20,7 @@ go_library(
|
||||
"//api/pagination:go_default_library",
|
||||
"//async/event:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/epoch/precompute:go_default_library",
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
blockfeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/block"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/operation"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
@@ -32,7 +32,7 @@ type Server struct {
|
||||
HeadFetcher blockchain.HeadFetcher
|
||||
CanonicalFetcher blockchain.CanonicalFetcher
|
||||
FinalizationFetcher blockchain.FinalizationFetcher
|
||||
DepositFetcher depositcache.DepositFetcher
|
||||
DepositFetcher cache.DepositFetcher
|
||||
BlockFetcher execution.POWBlockFetcher
|
||||
GenesisTimeFetcher blockchain.TimeFetcher
|
||||
StateNotifier statefeed.Notifier
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prysmaticlabs/prysm/v4/async/event"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache/depositcache"
|
||||
depositCache "github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
type infostream struct {
|
||||
ctx context.Context
|
||||
headFetcher blockchain.HeadFetcher
|
||||
depositFetcher depositcache.DepositFetcher
|
||||
depositFetcher depositCache.DepositFetcher
|
||||
blockFetcher execution.POWBlockFetcher
|
||||
beaconDB db.ReadOnlyDatabase
|
||||
pubKeys [][]byte
|
||||
|
||||
@@ -215,7 +215,9 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not get blinded blobs bundle")
|
||||
}
|
||||
log.WithField("blindBlobCount", len(bundle.BlobRoots))
|
||||
if bundle != nil {
|
||||
log.WithField("blindBlobCount", len(bundle.BlobRoots))
|
||||
}
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
|
||||
@@ -22,9 +22,15 @@ func setKzgCommitments(blk interfaces.SignedBeaconBlock, bundle *enginev1.BlobsB
|
||||
}
|
||||
|
||||
if blk.IsBlinded() {
|
||||
if blindBundle == nil {
|
||||
return nil
|
||||
}
|
||||
return blk.SetBlobKzgCommitments(blindBundle.KzgCommitments)
|
||||
}
|
||||
|
||||
if bundle == nil {
|
||||
return nil
|
||||
}
|
||||
return blk.SetBlobKzgCommitments(bundle.KzgCommitments)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
@@ -129,16 +130,19 @@ func (vs *Server) deposits(
|
||||
return pendingDeposits, nil
|
||||
}
|
||||
|
||||
func (vs *Server) depositTrie(ctx context.Context, canonicalEth1Data *ethpb.Eth1Data, canonicalEth1DataHeight *big.Int) (*trie.SparseMerkleTrie, error) {
|
||||
func (vs *Server) depositTrie(ctx context.Context, canonicalEth1Data *ethpb.Eth1Data, canonicalEth1DataHeight *big.Int) (cache.MerkleTree, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.depositTrie")
|
||||
defer span.End()
|
||||
|
||||
var depositTrie *trie.SparseMerkleTrie
|
||||
var depositTrie cache.MerkleTree
|
||||
|
||||
finalizedDeposits := vs.DepositFetcher.FinalizedDeposits(ctx)
|
||||
depositTrie = finalizedDeposits.Deposits
|
||||
upToEth1DataDeposits := vs.DepositFetcher.NonFinalizedDeposits(ctx, finalizedDeposits.MerkleTrieIndex, canonicalEth1DataHeight)
|
||||
insertIndex := finalizedDeposits.MerkleTrieIndex + 1
|
||||
finalizedDeposits, err := vs.DepositFetcher.FinalizedDeposits(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
depositTrie = finalizedDeposits.Deposits()
|
||||
upToEth1DataDeposits := vs.DepositFetcher.NonFinalizedDeposits(ctx, finalizedDeposits.MerkleTrieIndex(), canonicalEth1DataHeight)
|
||||
insertIndex := finalizedDeposits.MerkleTrieIndex() + 1
|
||||
|
||||
if shouldRebuildTrie(canonicalEth1Data.DepositCount, uint64(len(upToEth1DataDeposits))) {
|
||||
log.WithFields(logrus.Fields{
|
||||
@@ -169,7 +173,7 @@ func (vs *Server) depositTrie(ctx context.Context, canonicalEth1Data *ethpb.Eth1
|
||||
|
||||
// rebuilds our deposit trie by recreating it from all processed deposits till
|
||||
// specified eth1 block height.
|
||||
func (vs *Server) rebuildDepositTrie(ctx context.Context, canonicalEth1Data *ethpb.Eth1Data, canonicalEth1DataHeight *big.Int) (*trie.SparseMerkleTrie, error) {
|
||||
func (vs *Server) rebuildDepositTrie(ctx context.Context, canonicalEth1Data *ethpb.Eth1Data, canonicalEth1DataHeight *big.Int) (cache.MerkleTree, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.rebuildDepositTrie")
|
||||
defer span.End()
|
||||
|
||||
@@ -196,7 +200,7 @@ func (vs *Server) rebuildDepositTrie(ctx context.Context, canonicalEth1Data *eth
|
||||
}
|
||||
|
||||
// validate that the provided deposit trie matches up with the canonical eth1 data provided.
|
||||
func validateDepositTrie(trie *trie.SparseMerkleTrie, canonicalEth1Data *ethpb.Eth1Data) (bool, error) {
|
||||
func validateDepositTrie(trie cache.MerkleTree, canonicalEth1Data *ethpb.Eth1Data) (bool, error) {
|
||||
if trie == nil || canonicalEth1Data == nil {
|
||||
return false, errors.New("nil trie or eth1data provided")
|
||||
}
|
||||
@@ -213,7 +217,7 @@ func validateDepositTrie(trie *trie.SparseMerkleTrie, canonicalEth1Data *ethpb.E
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func constructMerkleProof(trie *trie.SparseMerkleTrie, index int, deposit *ethpb.Deposit) (*ethpb.Deposit, error) {
|
||||
func constructMerkleProof(trie cache.MerkleTree, index int, deposit *ethpb.Deposit) (*ethpb.Deposit, error) {
|
||||
proof, err := trie.MerkleProof(index)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not generate merkle proof for deposit at index %d", index)
|
||||
|
||||
@@ -1694,7 +1694,7 @@ func TestProposer_DepositTrie_RebuildTrie(t *testing.T) {
|
||||
// Mutate it since its a pointer
|
||||
d[0].Deposit.Data.WithdrawalCredentials = junkCreds[:]
|
||||
// Insert junk to corrupt trie.
|
||||
err = depositCache.InsertFinalizedDeposits(ctx, 2)
|
||||
err = depositCache.InsertFinalizedDeposits(ctx, 2, [32]byte{}, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add original back
|
||||
|
||||
@@ -50,7 +50,7 @@ type Server struct {
|
||||
FinalizationFetcher blockchain.FinalizationFetcher
|
||||
TimeFetcher blockchain.TimeFetcher
|
||||
BlockFetcher execution.POWBlockFetcher
|
||||
DepositFetcher depositcache.DepositFetcher
|
||||
DepositFetcher cache.DepositFetcher
|
||||
ChainStartFetcher execution.ChainStartFetcher
|
||||
Eth1InfoFetcher execution.ChainInfoFetcher
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
|
||||
@@ -115,7 +115,7 @@ type Config struct {
|
||||
PeersFetcher p2p.PeersProvider
|
||||
PeerManager p2p.PeerManager
|
||||
MetadataProvider p2p.MetadataProvider
|
||||
DepositFetcher depositcache.DepositFetcher
|
||||
DepositFetcher cache.DepositFetcher
|
||||
PendingDepositFetcher depositcache.PendingDepositsFetcher
|
||||
StateNotifier statefeed.Notifier
|
||||
BlockNotifier blockfeed.Notifier
|
||||
|
||||
@@ -66,6 +66,7 @@ type Flags struct {
|
||||
|
||||
EnableVerboseSigVerification bool // EnableVerboseSigVerification specifies whether to verify individual signature if batch verification fails
|
||||
EnableOptionalEngineMethods bool // EnableOptionalEngineMethods specifies whether to activate capella specific engine methods
|
||||
EnableEIP4881 bool // EnableEIP4881 specifies whether to use the deposit tree from EIP4881
|
||||
|
||||
PrepareAllPayloads bool // PrepareAllPayloads informs the engine to prepare a block on every slot.
|
||||
|
||||
@@ -250,6 +251,10 @@ func ConfigureBeaconChain(ctx *cli.Context) error {
|
||||
logEnabled(disableResourceManager)
|
||||
cfg.DisableResourceManager = true
|
||||
}
|
||||
if ctx.IsSet(enableEIP4881.Name) {
|
||||
logEnabled(enableEIP4881)
|
||||
cfg.EnableEIP4881 = true
|
||||
}
|
||||
cfg.AggregateIntervals = [3]time.Duration{aggregateFirstInterval.Value, aggregateSecondInterval.Value, aggregateThirdInterval.Value}
|
||||
Init(cfg)
|
||||
return nil
|
||||
|
||||
@@ -149,6 +149,10 @@ var (
|
||||
Name: "disable-build-block-parallel",
|
||||
Usage: "Disables building a beacon block in parallel for consensus and execution",
|
||||
}
|
||||
enableEIP4881 = &cli.BoolFlag{
|
||||
Name: "enable-eip-4881",
|
||||
Usage: "Enables the deposit tree specified in EIP4881",
|
||||
}
|
||||
disableResourceManager = &cli.BoolFlag{
|
||||
Name: "disable-resource-manager",
|
||||
Usage: "Disables running the libp2p resource manager",
|
||||
@@ -170,6 +174,7 @@ var (
|
||||
var devModeFlags = []cli.Flag{
|
||||
enableVerboseSigVerification,
|
||||
enableOptionalEngineMethods,
|
||||
enableEIP4881,
|
||||
}
|
||||
|
||||
// ValidatorFlags contains a list of all the feature flags that apply to the validator client.
|
||||
@@ -217,6 +222,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c
|
||||
aggregateFirstInterval,
|
||||
aggregateSecondInterval,
|
||||
aggregateThirdInterval,
|
||||
enableEIP4881,
|
||||
disableResourceManager,
|
||||
DisableRegistrationCache,
|
||||
disableAggregateParallel,
|
||||
|
||||
@@ -284,3 +284,8 @@ func (b *BeaconChainConfig) CurrentEpochAttestationsLength() uint64 {
|
||||
func DenebEnabled() bool {
|
||||
return BeaconConfig().DenebForkEpoch < math.MaxUint64
|
||||
}
|
||||
|
||||
// WithinDAPeriod checks if the block epoch is within MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS of the given current epoch.
|
||||
func WithinDAPeriod(block, current primitives.Epoch) bool {
|
||||
return block+BeaconNetworkConfig().MinEpochsForBlobsSidecarsRequest >= current
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ type ExecutionBlock struct {
|
||||
Transactions []*gethtypes.Transaction `json:"transactions"`
|
||||
TotalDifficulty string `json:"totalDifficulty"`
|
||||
Withdrawals []*Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
}
|
||||
|
||||
func (e *ExecutionBlock) MarshalJSON() ([]byte, error) {
|
||||
@@ -110,21 +108,11 @@ func (e *ExecutionBlock) UnmarshalJSON(enc []byte) error {
|
||||
edg, has := decoded["excessBlobGas"]
|
||||
if has && edg != nil {
|
||||
e.Version = version.Deneb
|
||||
uedg, err := hexutil.DecodeUint64(edg.(string))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to unmarshal excessBlobGas as hexutil.Uint64")
|
||||
}
|
||||
*e.ExcessBlobGas = hexutil.Uint64(uedg)
|
||||
}
|
||||
|
||||
dgu, has := decoded["blobGasUsed"]
|
||||
if has && dgu != nil {
|
||||
e.Version = version.Deneb
|
||||
udgu, err := hexutil.DecodeUint64(dgu.(string))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "blobGasUsed is not a string, can not decode")
|
||||
}
|
||||
*e.BlobGasUsed = hexutil.Uint64(udgu)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -566,6 +566,71 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
|
||||
require.DeepEqual(t, bytesutil.PadTo([]byte("address2"), 20), payloadPb.Withdrawals[1].Address)
|
||||
require.Equal(t, uint64(200), payloadPb.Withdrawals[1].Amount)
|
||||
})
|
||||
t.Run("execution block with deneb blob data", func(t *testing.T) {
|
||||
baseFeePerGas := big.NewInt(1770307273)
|
||||
blobGas := uint64(3000)
|
||||
excessGas := uint64(7000)
|
||||
want := &gethtypes.Header{
|
||||
Number: big.NewInt(1),
|
||||
ParentHash: common.BytesToHash([]byte("parent")),
|
||||
UncleHash: common.BytesToHash([]byte("uncle")),
|
||||
Coinbase: common.BytesToAddress([]byte("coinbase")),
|
||||
Root: common.BytesToHash([]byte("uncle")),
|
||||
TxHash: common.BytesToHash([]byte("txHash")),
|
||||
ReceiptHash: common.BytesToHash([]byte("receiptHash")),
|
||||
Bloom: gethtypes.BytesToBloom([]byte("bloom")),
|
||||
Difficulty: big.NewInt(2),
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Time: 5,
|
||||
BaseFee: baseFeePerGas,
|
||||
Extra: []byte("extraData"),
|
||||
MixDigest: common.BytesToHash([]byte("mix")),
|
||||
Nonce: gethtypes.EncodeNonce(6),
|
||||
BlobGasUsed: &blobGas,
|
||||
ExcessBlobGas: &excessGas,
|
||||
}
|
||||
enc, err := json.Marshal(want)
|
||||
require.NoError(t, err)
|
||||
|
||||
payloadItems := make(map[string]interface{})
|
||||
require.NoError(t, json.Unmarshal(enc, &payloadItems))
|
||||
|
||||
blockHash := want.Hash()
|
||||
payloadItems["hash"] = blockHash.String()
|
||||
payloadItems["totalDifficulty"] = "0x393a2e53de197c"
|
||||
payloadItems["transactions"] = []string{"0xd57870623ea84ac3e2ffafbee9417fd1263b825b1107b8d606c25460dabeb693"}
|
||||
|
||||
encodedPayloadItems, err := json.Marshal(payloadItems)
|
||||
require.NoError(t, err)
|
||||
|
||||
payloadPb := &enginev1.ExecutionBlock{}
|
||||
require.NoError(t, json.Unmarshal(encodedPayloadItems, payloadPb))
|
||||
|
||||
require.DeepEqual(t, blockHash, payloadPb.Hash)
|
||||
require.DeepEqual(t, want.Number, payloadPb.Number)
|
||||
require.DeepEqual(t, want.ParentHash, payloadPb.ParentHash)
|
||||
require.DeepEqual(t, want.UncleHash, payloadPb.UncleHash)
|
||||
require.DeepEqual(t, want.Coinbase, payloadPb.Coinbase)
|
||||
require.DeepEqual(t, want.Root, payloadPb.Root)
|
||||
require.DeepEqual(t, want.TxHash, payloadPb.TxHash)
|
||||
require.DeepEqual(t, want.ReceiptHash, payloadPb.ReceiptHash)
|
||||
require.DeepEqual(t, want.Bloom, payloadPb.Bloom)
|
||||
require.DeepEqual(t, want.Difficulty, payloadPb.Difficulty)
|
||||
require.DeepEqual(t, payloadItems["totalDifficulty"], payloadPb.TotalDifficulty)
|
||||
require.DeepEqual(t, want.GasUsed, payloadPb.GasUsed)
|
||||
require.DeepEqual(t, want.GasLimit, payloadPb.GasLimit)
|
||||
require.DeepEqual(t, want.Time, payloadPb.Time)
|
||||
require.DeepEqual(t, want.BaseFee, payloadPb.BaseFee)
|
||||
require.DeepEqual(t, want.Extra, payloadPb.Extra)
|
||||
require.DeepEqual(t, want.MixDigest, payloadPb.MixDigest)
|
||||
require.DeepEqual(t, want.Nonce, payloadPb.Nonce)
|
||||
require.DeepEqual(t, want.BlobGasUsed, payloadPb.BlobGasUsed)
|
||||
require.DeepEqual(t, want.ExcessBlobGas, payloadPb.ExcessBlobGas)
|
||||
|
||||
// Expect no transaction objects in the unmarshaled data.
|
||||
require.Equal(t, 0, len(payloadPb.Transactions))
|
||||
})
|
||||
}
|
||||
|
||||
func TestPayloadIDBytes_MarshalUnmarshalJSON(t *testing.T) {
|
||||
|
||||
327
proto/prysm/v1alpha1/powchain.pb.go
generated
327
proto/prysm/v1alpha1/powchain.pb.go
generated
@@ -31,6 +31,7 @@ type ETH1ChainData struct {
|
||||
BeaconState *BeaconState `protobuf:"bytes,3,opt,name=beacon_state,json=beaconState,proto3" json:"beacon_state,omitempty"`
|
||||
Trie *SparseMerkleTrie `protobuf:"bytes,4,opt,name=trie,proto3" json:"trie,omitempty"`
|
||||
DepositContainers []*DepositContainer `protobuf:"bytes,5,rep,name=deposit_containers,json=depositContainers,proto3" json:"deposit_containers,omitempty"`
|
||||
DepositSnapshot *DepositSnapshot `protobuf:"bytes,6,opt,name=deposit_snapshot,json=depositSnapshot,proto3" json:"deposit_snapshot,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ETH1ChainData) Reset() {
|
||||
@@ -100,6 +101,92 @@ func (x *ETH1ChainData) GetDepositContainers() []*DepositContainer {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ETH1ChainData) GetDepositSnapshot() *DepositSnapshot {
|
||||
if x != nil {
|
||||
return x.DepositSnapshot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DepositSnapshot struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Finalized [][]byte `protobuf:"bytes,1,rep,name=finalized,proto3" json:"finalized,omitempty"`
|
||||
DepositRoot []byte `protobuf:"bytes,2,opt,name=deposit_root,json=depositRoot,proto3" json:"deposit_root,omitempty"`
|
||||
DepositCount uint64 `protobuf:"varint,3,opt,name=deposit_count,json=depositCount,proto3" json:"deposit_count,omitempty"`
|
||||
ExecutionHash []byte `protobuf:"bytes,4,opt,name=execution_hash,json=executionHash,proto3" json:"execution_hash,omitempty"`
|
||||
ExecutionDepth uint64 `protobuf:"varint,5,opt,name=execution_depth,json=executionDepth,proto3" json:"execution_depth,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) Reset() {
|
||||
*x = DepositSnapshot{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DepositSnapshot) ProtoMessage() {}
|
||||
|
||||
func (x *DepositSnapshot) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DepositSnapshot.ProtoReflect.Descriptor instead.
|
||||
func (*DepositSnapshot) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) GetFinalized() [][]byte {
|
||||
if x != nil {
|
||||
return x.Finalized
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) GetDepositRoot() []byte {
|
||||
if x != nil {
|
||||
return x.DepositRoot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) GetDepositCount() uint64 {
|
||||
if x != nil {
|
||||
return x.DepositCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) GetExecutionHash() []byte {
|
||||
if x != nil {
|
||||
return x.ExecutionHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DepositSnapshot) GetExecutionDepth() uint64 {
|
||||
if x != nil {
|
||||
return x.ExecutionDepth
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type LatestETH1Data struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -114,7 +201,7 @@ type LatestETH1Data struct {
|
||||
func (x *LatestETH1Data) Reset() {
|
||||
*x = LatestETH1Data{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[1]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -127,7 +214,7 @@ func (x *LatestETH1Data) String() string {
|
||||
func (*LatestETH1Data) ProtoMessage() {}
|
||||
|
||||
func (x *LatestETH1Data) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[1]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -140,7 +227,7 @@ func (x *LatestETH1Data) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use LatestETH1Data.ProtoReflect.Descriptor instead.
|
||||
func (*LatestETH1Data) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{1}
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *LatestETH1Data) GetBlockHeight() uint64 {
|
||||
@@ -186,7 +273,7 @@ type ChainStartData struct {
|
||||
func (x *ChainStartData) Reset() {
|
||||
*x = ChainStartData{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[2]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -199,7 +286,7 @@ func (x *ChainStartData) String() string {
|
||||
func (*ChainStartData) ProtoMessage() {}
|
||||
|
||||
func (x *ChainStartData) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[2]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -212,7 +299,7 @@ func (x *ChainStartData) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ChainStartData.ProtoReflect.Descriptor instead.
|
||||
func (*ChainStartData) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{2}
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ChainStartData) GetChainstarted() bool {
|
||||
@@ -263,7 +350,7 @@ type SparseMerkleTrie struct {
|
||||
func (x *SparseMerkleTrie) Reset() {
|
||||
*x = SparseMerkleTrie{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[3]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -276,7 +363,7 @@ func (x *SparseMerkleTrie) String() string {
|
||||
func (*SparseMerkleTrie) ProtoMessage() {}
|
||||
|
||||
func (x *SparseMerkleTrie) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[3]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -289,7 +376,7 @@ func (x *SparseMerkleTrie) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use SparseMerkleTrie.ProtoReflect.Descriptor instead.
|
||||
func (*SparseMerkleTrie) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{3}
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *SparseMerkleTrie) GetDepth() uint64 {
|
||||
@@ -324,7 +411,7 @@ type TrieLayer struct {
|
||||
func (x *TrieLayer) Reset() {
|
||||
*x = TrieLayer{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[4]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -337,7 +424,7 @@ func (x *TrieLayer) String() string {
|
||||
func (*TrieLayer) ProtoMessage() {}
|
||||
|
||||
func (x *TrieLayer) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[4]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -350,7 +437,7 @@ func (x *TrieLayer) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use TrieLayer.ProtoReflect.Descriptor instead.
|
||||
func (*TrieLayer) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{4}
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *TrieLayer) GetLayer() [][]byte {
|
||||
@@ -374,7 +461,7 @@ type DepositContainer struct {
|
||||
func (x *DepositContainer) Reset() {
|
||||
*x = DepositContainer{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[5]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -387,7 +474,7 @@ func (x *DepositContainer) String() string {
|
||||
func (*DepositContainer) ProtoMessage() {}
|
||||
|
||||
func (x *DepositContainer) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[5]
|
||||
mi := &file_proto_prysm_v1alpha1_powchain_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -400,7 +487,7 @@ func (x *DepositContainer) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DepositContainer.ProtoReflect.Descriptor instead.
|
||||
func (*DepositContainer) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{5}
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *DepositContainer) GetIndex() int64 {
|
||||
@@ -442,7 +529,7 @@ var file_proto_prysm_v1alpha1_powchain_proto_rawDesc = []byte{
|
||||
0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79,
|
||||
0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63,
|
||||
0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e,
|
||||
0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1,
|
||||
0x03, 0x0a, 0x0d, 0x45, 0x54, 0x48, 0x31, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61,
|
||||
0x12, 0x51, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x74, 0x68, 0x31,
|
||||
0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74,
|
||||
@@ -467,67 +554,85 @@ var file_proto_prysm_v1alpha1_powchain_proto_rawDesc = []byte{
|
||||
0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x11, 0x64, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22,
|
||||
0xa3, 0x01, 0x0a, 0x0e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61,
|
||||
0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61,
|
||||
0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
|
||||
0x61, 0x73, 0x68, 0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x04, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64,
|
||||
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x8b, 0x02, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53,
|
||||
0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
|
||||
0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x0b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74,
|
||||
0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
|
||||
0x45, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61,
|
||||
0x74, 0x61, 0x12, 0x4f, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74,
|
||||
0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
|
||||
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52,
|
||||
0x12, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x73, 0x22, 0x89, 0x01, 0x0a, 0x10, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65,
|
||||
0x72, 0x6b, 0x6c, 0x65, 0x54, 0x72, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74,
|
||||
0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x38,
|
||||
0x0a, 0x06, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72,
|
||||
0x52, 0x06, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67,
|
||||
0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c,
|
||||
0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22,
|
||||
0x21, 0x0a, 0x09, 0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a,
|
||||
0x11, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x65, 0x74, 0x68, 0x31, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x64, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68,
|
||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x07, 0x64, 0x65, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72,
|
||||
0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12,
|
||||
0x51, 0x0a, 0x10, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73,
|
||||
0x68, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
|
||||
0x74, 0x52, 0x0f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68,
|
||||
0x6f, 0x74, 0x22, 0xc7, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x6e,
|
||||
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c,
|
||||
0x69, 0x7a, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f,
|
||||
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
|
||||
0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e,
|
||||
0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48,
|
||||
0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x65, 0x78,
|
||||
0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x70, 0x74, 0x68, 0x22, 0xa3, 0x01, 0x0a,
|
||||
0x0e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x45, 0x54, 0x48, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68,
|
||||
0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x8b, 0x02, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x72,
|
||||
0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x65, 0x6e,
|
||||
0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x74, 0x68,
|
||||
0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x4f, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x42, 0x0d, 0x50, 0x6f, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 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, 0x70,
|
||||
0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74,
|
||||
0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68,
|
||||
0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x12, 0x63, 0x68,
|
||||
0x61, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73,
|
||||
0x22, 0x89, 0x01, 0x0a, 0x10, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x65, 0x72, 0x6b, 0x6c,
|
||||
0x65, 0x54, 0x72, 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x06, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
|
||||
0x68, 0x61, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
|
||||
0x6c, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x6f,
|
||||
0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x21, 0x0a, 0x09,
|
||||
0x54, 0x72, 0x69, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22,
|
||||
0xb1, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x74,
|
||||
0x68, 0x31, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x65, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69,
|
||||
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
|
||||
0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x07, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52,
|
||||
0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65,
|
||||
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x42, 0x0d, 0x50, 0x6f, 0x77, 0x63, 0x68, 0x61, 0x69, 0x6e, 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, 0x70, 0x72, 0x79, 0x73,
|
||||
0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02,
|
||||
0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -542,33 +647,35 @@ func file_proto_prysm_v1alpha1_powchain_proto_rawDescGZIP() []byte {
|
||||
return file_proto_prysm_v1alpha1_powchain_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_prysm_v1alpha1_powchain_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_proto_prysm_v1alpha1_powchain_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_proto_prysm_v1alpha1_powchain_proto_goTypes = []interface{}{
|
||||
(*ETH1ChainData)(nil), // 0: ethereum.eth.v1alpha1.ETH1ChainData
|
||||
(*LatestETH1Data)(nil), // 1: ethereum.eth.v1alpha1.LatestETH1Data
|
||||
(*ChainStartData)(nil), // 2: ethereum.eth.v1alpha1.ChainStartData
|
||||
(*SparseMerkleTrie)(nil), // 3: ethereum.eth.v1alpha1.SparseMerkleTrie
|
||||
(*TrieLayer)(nil), // 4: ethereum.eth.v1alpha1.TrieLayer
|
||||
(*DepositContainer)(nil), // 5: ethereum.eth.v1alpha1.DepositContainer
|
||||
(*BeaconState)(nil), // 6: ethereum.eth.v1alpha1.BeaconState
|
||||
(*Eth1Data)(nil), // 7: ethereum.eth.v1alpha1.Eth1Data
|
||||
(*Deposit)(nil), // 8: ethereum.eth.v1alpha1.Deposit
|
||||
(*DepositSnapshot)(nil), // 1: ethereum.eth.v1alpha1.DepositSnapshot
|
||||
(*LatestETH1Data)(nil), // 2: ethereum.eth.v1alpha1.LatestETH1Data
|
||||
(*ChainStartData)(nil), // 3: ethereum.eth.v1alpha1.ChainStartData
|
||||
(*SparseMerkleTrie)(nil), // 4: ethereum.eth.v1alpha1.SparseMerkleTrie
|
||||
(*TrieLayer)(nil), // 5: ethereum.eth.v1alpha1.TrieLayer
|
||||
(*DepositContainer)(nil), // 6: ethereum.eth.v1alpha1.DepositContainer
|
||||
(*BeaconState)(nil), // 7: ethereum.eth.v1alpha1.BeaconState
|
||||
(*Eth1Data)(nil), // 8: ethereum.eth.v1alpha1.Eth1Data
|
||||
(*Deposit)(nil), // 9: ethereum.eth.v1alpha1.Deposit
|
||||
}
|
||||
var file_proto_prysm_v1alpha1_powchain_proto_depIdxs = []int32{
|
||||
1, // 0: ethereum.eth.v1alpha1.ETH1ChainData.current_eth1_data:type_name -> ethereum.eth.v1alpha1.LatestETH1Data
|
||||
2, // 1: ethereum.eth.v1alpha1.ETH1ChainData.chainstart_data:type_name -> ethereum.eth.v1alpha1.ChainStartData
|
||||
6, // 2: ethereum.eth.v1alpha1.ETH1ChainData.beacon_state:type_name -> ethereum.eth.v1alpha1.BeaconState
|
||||
3, // 3: ethereum.eth.v1alpha1.ETH1ChainData.trie:type_name -> ethereum.eth.v1alpha1.SparseMerkleTrie
|
||||
5, // 4: ethereum.eth.v1alpha1.ETH1ChainData.deposit_containers:type_name -> ethereum.eth.v1alpha1.DepositContainer
|
||||
7, // 5: ethereum.eth.v1alpha1.ChainStartData.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
8, // 6: ethereum.eth.v1alpha1.ChainStartData.chainstart_deposits:type_name -> ethereum.eth.v1alpha1.Deposit
|
||||
4, // 7: ethereum.eth.v1alpha1.SparseMerkleTrie.layers:type_name -> ethereum.eth.v1alpha1.TrieLayer
|
||||
8, // 8: ethereum.eth.v1alpha1.DepositContainer.deposit:type_name -> ethereum.eth.v1alpha1.Deposit
|
||||
9, // [9:9] is the sub-list for method output_type
|
||||
9, // [9:9] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
2, // 0: ethereum.eth.v1alpha1.ETH1ChainData.current_eth1_data:type_name -> ethereum.eth.v1alpha1.LatestETH1Data
|
||||
3, // 1: ethereum.eth.v1alpha1.ETH1ChainData.chainstart_data:type_name -> ethereum.eth.v1alpha1.ChainStartData
|
||||
7, // 2: ethereum.eth.v1alpha1.ETH1ChainData.beacon_state:type_name -> ethereum.eth.v1alpha1.BeaconState
|
||||
4, // 3: ethereum.eth.v1alpha1.ETH1ChainData.trie:type_name -> ethereum.eth.v1alpha1.SparseMerkleTrie
|
||||
6, // 4: ethereum.eth.v1alpha1.ETH1ChainData.deposit_containers:type_name -> ethereum.eth.v1alpha1.DepositContainer
|
||||
1, // 5: ethereum.eth.v1alpha1.ETH1ChainData.deposit_snapshot:type_name -> ethereum.eth.v1alpha1.DepositSnapshot
|
||||
8, // 6: ethereum.eth.v1alpha1.ChainStartData.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
9, // 7: ethereum.eth.v1alpha1.ChainStartData.chainstart_deposits:type_name -> ethereum.eth.v1alpha1.Deposit
|
||||
5, // 8: ethereum.eth.v1alpha1.SparseMerkleTrie.layers:type_name -> ethereum.eth.v1alpha1.TrieLayer
|
||||
9, // 9: ethereum.eth.v1alpha1.DepositContainer.deposit:type_name -> ethereum.eth.v1alpha1.Deposit
|
||||
10, // [10:10] is the sub-list for method output_type
|
||||
10, // [10:10] is the sub-list for method input_type
|
||||
10, // [10:10] is the sub-list for extension type_name
|
||||
10, // [10:10] is the sub-list for extension extendee
|
||||
0, // [0:10] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_prysm_v1alpha1_powchain_proto_init() }
|
||||
@@ -592,7 +699,7 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*LatestETH1Data); i {
|
||||
switch v := v.(*DepositSnapshot); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -604,7 +711,7 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ChainStartData); i {
|
||||
switch v := v.(*LatestETH1Data); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -616,7 +723,7 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SparseMerkleTrie); i {
|
||||
switch v := v.(*ChainStartData); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -628,7 +735,7 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TrieLayer); i {
|
||||
switch v := v.(*SparseMerkleTrie); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -640,6 +747,18 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TrieLayer); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_powchain_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DepositContainer); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -658,7 +777,7 @@ func file_proto_prysm_v1alpha1_powchain_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_v1alpha1_powchain_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -20,8 +20,17 @@ message ETH1ChainData {
|
||||
BeaconState beacon_state = 3;
|
||||
SparseMerkleTrie trie = 4;
|
||||
repeated DepositContainer deposit_containers = 5;
|
||||
DepositSnapshot deposit_snapshot = 6;
|
||||
}
|
||||
|
||||
// DepositSnapshot represents an EIP-4881 deposit snapshot
|
||||
message DepositSnapshot {
|
||||
repeated bytes finalized = 1;
|
||||
bytes deposit_root = 2;
|
||||
uint64 deposit_count = 3;
|
||||
bytes execution_hash = 4;
|
||||
uint64 execution_depth = 5;
|
||||
}
|
||||
// LatestETH1Data contains the current state of the eth1 chain.
|
||||
message LatestETH1Data {
|
||||
uint64 block_height = 2;
|
||||
|
||||
@@ -85,6 +85,8 @@ func wrapBlock(b *v1alpha1.BeaconBlockContainer) interfaces.ReadOnlyBeaconBlock
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.BellatrixBlock)
|
||||
case *v1alpha1.BeaconBlockContainer_CapellaBlock:
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.CapellaBlock)
|
||||
case *v1alpha1.BeaconBlockContainer_BlindedCapellaBlock:
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.BlindedCapellaBlock)
|
||||
}
|
||||
if err != nil {
|
||||
panic("no block")
|
||||
|
||||
Reference in New Issue
Block a user