mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
177 Commits
blob-rotat
...
kintsugi-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63a8b0804e | ||
|
|
f572ba9d56 | ||
|
|
4b75b991dd | ||
|
|
cbdb3c9e86 | ||
|
|
08a5155ee3 | ||
|
|
f99a0419ef | ||
|
|
4ad31f9c05 | ||
|
|
26876d64d7 | ||
|
|
3450923661 | ||
|
|
aba628b56b | ||
|
|
5effb92d11 | ||
|
|
2b55368c99 | ||
|
|
327903b7bb | ||
|
|
77f815a39f | ||
|
|
80dc725412 | ||
|
|
263c18992e | ||
|
|
9e220f9052 | ||
|
|
99878d104c | ||
|
|
a870bf7a74 | ||
|
|
dc42ff382f | ||
|
|
53b78a38a3 | ||
|
|
b45826e731 | ||
|
|
7b59ecac5e | ||
|
|
9149178a9c | ||
|
|
51ef502b04 | ||
|
|
8d891821ee | ||
|
|
762863ce6a | ||
|
|
41f5fa7524 | ||
|
|
09744bac70 | ||
|
|
f5db847237 | ||
|
|
8600f70b0b | ||
|
|
6fe430de44 | ||
|
|
42a5f96d3f | ||
|
|
e7f0fcf202 | ||
|
|
5ae564f1bf | ||
|
|
719109c219 | ||
|
|
64533a4b0c | ||
|
|
9fecd761d7 | ||
|
|
f84c95667c | ||
|
|
9af081797e | ||
|
|
e4e9f12c8b | ||
|
|
2f4e8beae6 | ||
|
|
81c7b90d26 | ||
|
|
dd3d65ff18 | ||
|
|
ac5a227aeb | ||
|
|
33f4d5c3cc | ||
|
|
67d7f8baee | ||
|
|
3c54aef7b1 | ||
|
|
938c28c42e | ||
|
|
8ddb2c26c4 | ||
|
|
cf0e78c2f6 | ||
|
|
4c0b262fdc | ||
|
|
33e675e204 | ||
|
|
e599f6a8a1 | ||
|
|
49c9ab9fda | ||
|
|
f90dec287b | ||
|
|
12c36cff9d | ||
|
|
bc565d9ee6 | ||
|
|
db67d5bad8 | ||
|
|
3bc0c2be54 | ||
|
|
1bed9ef749 | ||
|
|
ec772beeaf | ||
|
|
56407dde02 | ||
|
|
445f17881e | ||
|
|
183d40d8f1 | ||
|
|
87bc6aa5e5 | ||
|
|
5b5065b01d | ||
|
|
ee1c567561 | ||
|
|
ff1416c98d | ||
|
|
471c94031f | ||
|
|
9863fb3d6a | ||
|
|
f3c2d1a00b | ||
|
|
5d8879a4df | ||
|
|
abea0a11bc | ||
|
|
80ce1603bd | ||
|
|
ca478244e0 | ||
|
|
8a864b66a1 | ||
|
|
72f3b9e84b | ||
|
|
493e95060f | ||
|
|
e7e1ecd72f | ||
|
|
c286ac8b87 | ||
|
|
bde315224c | ||
|
|
00520705bc | ||
|
|
c7fcd804d7 | ||
|
|
985ac2e848 | ||
|
|
f4a0e98926 | ||
|
|
5f93ff10ea | ||
|
|
544248f60f | ||
|
|
3b41968510 | ||
|
|
7fc418042a | ||
|
|
9a03946706 | ||
|
|
33dd6dd5f2 | ||
|
|
56542e1958 | ||
|
|
e82d7b4c0b | ||
|
|
6cb69d8ff0 | ||
|
|
70b55a0191 | ||
|
|
50f4951194 | ||
|
|
1a14f2368d | ||
|
|
bb8cad58f1 | ||
|
|
05412c1f0e | ||
|
|
b03441fed8 | ||
|
|
fa7d7cef69 | ||
|
|
1caa6c969f | ||
|
|
eeb7d5bbfb | ||
|
|
d7c7d150b1 | ||
|
|
63c4d2eb2b | ||
|
|
9de1f694a0 | ||
|
|
8a79d06cbd | ||
|
|
5290ad93b8 | ||
|
|
2128208ef7 | ||
|
|
296323719c | ||
|
|
5e9583ea85 | ||
|
|
17196e0f80 | ||
|
|
c50d54000d | ||
|
|
85b3061d1b | ||
|
|
0146c5317a | ||
|
|
fcbc48ffd9 | ||
|
|
76ee51af9d | ||
|
|
370b0b97ed | ||
|
|
990ebd3fe3 | ||
|
|
54449c72e8 | ||
|
|
1dbd0b98eb | ||
|
|
09c3896c6b | ||
|
|
d494845e19 | ||
|
|
4d0c0f7234 | ||
|
|
bfe570b1aa | ||
|
|
56db696823 | ||
|
|
d312e15db8 | ||
|
|
907d4cf7e6 | ||
|
|
891353d6ad | ||
|
|
0adc08660c | ||
|
|
de31425dcd | ||
|
|
2094e0f21f | ||
|
|
2c6f554500 | ||
|
|
18a1e07711 | ||
|
|
5e432f5aaa | ||
|
|
284e2696cb | ||
|
|
7547aaa6ce | ||
|
|
953315c2cc | ||
|
|
9662d06b08 | ||
|
|
ecaea26ace | ||
|
|
63819e2690 | ||
|
|
a6d0cd06b3 | ||
|
|
2dbe4f5e67 | ||
|
|
2689d6814d | ||
|
|
69a681ddc0 | ||
|
|
7f9f1fd36c | ||
|
|
57c97eb561 | ||
|
|
f0f94a8193 | ||
|
|
87b0bf2c2a | ||
|
|
d8ad317dec | ||
|
|
ab5f488cf4 | ||
|
|
296d7464ad | ||
|
|
221c542e4f | ||
|
|
7ad32aaa96 | ||
|
|
3dc0969c0c | ||
|
|
0e18e835c3 | ||
|
|
8adfbfc382 | ||
|
|
68b0b5e0ce | ||
|
|
eede309e0f | ||
|
|
b11628dc53 | ||
|
|
ea3ae22d3b | ||
|
|
02bb39ddeb | ||
|
|
1618c1f55d | ||
|
|
73c8493fd7 | ||
|
|
a4f59a4f15 | ||
|
|
3c497efdb8 | ||
|
|
9f5daafbb7 | ||
|
|
11d7ffdfa8 | ||
|
|
c26b3305e6 | ||
|
|
38d8b63fbf | ||
|
|
aea67405c8 | ||
|
|
57d830f8b3 | ||
|
|
ac4b1ef4ea | ||
|
|
1d32119f5a | ||
|
|
3540cc7b05 | ||
|
|
191e7767a6 |
@@ -65,6 +65,7 @@ go_library(
|
||||
"//crypto/bls:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||
@@ -73,6 +74,8 @@ go_library(
|
||||
"//time:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_emicklei_dot//:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//eth/catalyst:go_default_library",
|
||||
"@com_github_holiman_uint256//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
|
||||
@@ -40,6 +40,7 @@ func logStateTransitionData(b block.BeaconBlock) {
|
||||
log = log.WithField("syncBitsCount", agg.SyncCommitteeBits.Count())
|
||||
}
|
||||
}
|
||||
// TODO_MERGE: Add payload logging here
|
||||
log.Info("Finished applying state transition")
|
||||
}
|
||||
|
||||
@@ -51,11 +52,11 @@ func logBlockSyncStatus(block block.BeaconBlock, blockRoot [32]byte, finalized *
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": block.Slot(),
|
||||
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
|
||||
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
|
||||
"blockRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
|
||||
"parentRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
|
||||
"epoch": slots.ToEpoch(block.Slot()),
|
||||
"finalizedEpoch": finalized.Epoch,
|
||||
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
|
||||
"parentRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(block.ParentRoot())[:8]),
|
||||
"version": version.String(block.Version()),
|
||||
}).Info("Synced new block")
|
||||
log.WithFields(logrus.Fields{
|
||||
|
||||
@@ -50,6 +50,14 @@ func WithChainStartFetcher(f powchain.ChainStartFetcher) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithExecutionEngineCaller to call execution engine.
|
||||
func WithExecutionEngineCaller(c powchain.ExecutionEngineCaller) Option {
|
||||
return func(s *Service) error {
|
||||
s.cfg.ExecutionEngineCaller = c
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDepositCache for deposit lifecycle after chain inclusion.
|
||||
func WithDepositCache(c *depositcache.DepositCache) Option {
|
||||
return func(s *Service) error {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
// is_parent_total_difficulty_valid = parent.total_difficulty < TERMINAL_TOTAL_DIFFICULTY
|
||||
// return is_total_difficulty_reached and is_parent_total_difficulty_valid
|
||||
func validTerminalPowBlock(currentDifficulty *uint256.Int, parentDifficulty *uint256.Int) bool {
|
||||
ttd := uint256.NewInt(params.BeaconConfig().TerminalTotalDifficulty)
|
||||
ttd := params.BeaconConfig().TerminalTotalDifficulty
|
||||
totalDifficultyReached := currentDifficulty.Cmp(ttd) >= 0
|
||||
parentTotalDifficultyValid := ttd.Cmp(parentDifficulty) > 0
|
||||
return totalDifficultyReached && parentTotalDifficultyValid
|
||||
|
||||
@@ -61,7 +61,7 @@ func Test_validTerminalPowBlock(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := params.BeaconConfig()
|
||||
cfg.TerminalTotalDifficulty = tt.ttd
|
||||
cfg.TerminalTotalDifficulty = uint256.NewInt(tt.ttd)
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
if got := validTerminalPowBlock(tt.currentDifficulty, tt.parentDifficulty); got != tt.want {
|
||||
t.Errorf("validTerminalPowBlock() = %v, want %v", got, tt.want)
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
@@ -17,11 +23,14 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/monitoring/tracing"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
|
||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@@ -98,11 +107,44 @@ func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, b
|
||||
return err
|
||||
}
|
||||
|
||||
if preState.Version() == version.Bellatrix {
|
||||
mergeTransitionBlk, err := blocks.MergeTransitionBlock(preState, signed.Block().Body())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not check if merge block is terminal")
|
||||
}
|
||||
if mergeTransitionBlk {
|
||||
if err := s.validateTerminalBlock(signed); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body := signed.Block().Body()
|
||||
// TODO_MERGE: Break `ExecuteStateTransition` into per_slot and block processing so we can call `ExecutePayload` in the middle.
|
||||
postState, err := transition.ExecuteStateTransition(ctx, preState, signed)
|
||||
if err != nil {
|
||||
// TODO_MERGE: Notify execution client in the event of invalid conensus block
|
||||
return err
|
||||
}
|
||||
|
||||
if postState.Version() == version.Bellatrix {
|
||||
executionEnabled, err := blocks.ExecutionEnabled(postState, body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not check if execution is enabled")
|
||||
}
|
||||
if executionEnabled {
|
||||
payload, err := body.ExecutionPayload()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get body execution payload")
|
||||
}
|
||||
// This is not the earliest we can call `ExecutePayload`, see above to do as the soonest we can call is after per_slot processing.
|
||||
_, err = s.cfg.ExecutionEngineCaller.ExecutePayload(ctx, executionPayloadToExecutableData(payload))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not execute payload")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We add a proposer score boost to fork choice for the block root if applicable, right after
|
||||
// running a successful state transition for the block.
|
||||
if err := s.cfg.ForkChoiceStore.BoostProposerRoot(
|
||||
@@ -174,8 +216,52 @@ func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, b
|
||||
if err := s.updateHead(ctx, balances); err != nil {
|
||||
log.WithError(err).Warn("Could not update head")
|
||||
}
|
||||
|
||||
if err := s.saveSyncedTipsDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Notify execution layer with fork choice head update if this is post merge block.
|
||||
if postState.Version() == version.Bellatrix {
|
||||
executionEnabled, err := blocks.ExecutionEnabled(postState, body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not check if execution is enabled")
|
||||
}
|
||||
if executionEnabled {
|
||||
// Spawn the update task, without waiting for it to complete.
|
||||
go func() {
|
||||
headPayload, err := s.headBlock().Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
log.WithError(err)
|
||||
return
|
||||
}
|
||||
// TODO_MERGE: Loading the finalized block from DB on per block is not ideal. Finalized block should be cached here
|
||||
finalizedBlock, err := s.cfg.BeaconDB.Block(ctx, bytesutil.ToBytes32(finalized.Root))
|
||||
if err != nil {
|
||||
log.WithError(err)
|
||||
return
|
||||
}
|
||||
finalizedBlockHash := params.BeaconConfig().ZeroHash[:]
|
||||
if finalizedBlock != nil && finalizedBlock.Version() == version.Bellatrix {
|
||||
finalizedPayload, err := finalizedBlock.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
log.WithError(err)
|
||||
return
|
||||
}
|
||||
finalizedBlockHash = finalizedPayload.BlockHash
|
||||
}
|
||||
|
||||
f := catalyst.ForkchoiceStateV1{
|
||||
HeadBlockHash: common.BytesToHash(headPayload.BlockHash),
|
||||
SafeBlockHash: common.BytesToHash(headPayload.BlockHash),
|
||||
FinalizedBlockHash: common.BytesToHash(finalizedBlockHash),
|
||||
}
|
||||
if err := s.cfg.ExecutionEngineCaller.NotifyForkChoiceValidated(ctx, f); err != nil {
|
||||
log.WithError(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return errors.Wrap(err, "could not save synced tips")
|
||||
}
|
||||
|
||||
@@ -285,10 +371,68 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
||||
var set *bls.SignatureBatch
|
||||
boundaries := make(map[[32]byte]state.BeaconState)
|
||||
for i, b := range blks {
|
||||
if preState.Version() == version.Bellatrix {
|
||||
mergeTransitionBlk, err := blocks.MergeTransitionBlock(preState, b.Block().Body())
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not check if merge block is terminal")
|
||||
}
|
||||
if mergeTransitionBlk {
|
||||
if err := s.validateTerminalBlock(b); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
set, preState, err = transition.ExecuteStateTransitionNoVerifyAnySig(ctx, preState, b)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if preState.Version() == version.Bellatrix {
|
||||
executionEnabled, err := blocks.ExecutionEnabled(preState, b.Block().Body())
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not check if execution is enabled")
|
||||
}
|
||||
if executionEnabled {
|
||||
payload, err := b.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not get body execution payload")
|
||||
}
|
||||
_, err = s.cfg.ExecutionEngineCaller.ExecutePayload(ctx, executionPayloadToExecutableData(payload))
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "could not execute payload")
|
||||
}
|
||||
headPayload, err := s.headBlock().Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
}
|
||||
// TODO_MERGE: Loading the finalized block from DB on per block is not ideal. Finalized block should be cached here
|
||||
finalizedBlock, err := s.cfg.BeaconDB.Block(ctx, bytesutil.ToBytes32(preState.FinalizedCheckpoint().Root))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
}
|
||||
finalizedBlockHash := params.BeaconConfig().ZeroHash[:]
|
||||
if finalizedBlock != nil && finalizedBlock.Version() == version.Bellatrix {
|
||||
finalizedPayload, err := finalizedBlock.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
}
|
||||
finalizedBlockHash = finalizedPayload.BlockHash
|
||||
}
|
||||
|
||||
f := catalyst.ForkchoiceStateV1{
|
||||
HeadBlockHash: common.BytesToHash(headPayload.BlockHash),
|
||||
SafeBlockHash: common.BytesToHash(headPayload.BlockHash),
|
||||
FinalizedBlockHash: common.BytesToHash(finalizedBlockHash),
|
||||
}
|
||||
if err := s.cfg.ExecutionEngineCaller.NotifyForkChoiceValidated(ctx, f); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save potential boundary states.
|
||||
if slots.IsEpochStart(preState.Slot()) {
|
||||
boundaries[blockRoots[i]] = preState.Copy()
|
||||
@@ -298,6 +442,7 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
|
||||
}
|
||||
jCheckpoints[i] = preState.CurrentJustifiedCheckpoint()
|
||||
fCheckpoints[i] = preState.FinalizedCheckpoint()
|
||||
|
||||
sigSet.Join(set)
|
||||
}
|
||||
verify, err := sigSet.Verify()
|
||||
@@ -510,6 +655,107 @@ func (s *Service) pruneCanonicalAttsFromPool(ctx context.Context, r [32]byte, b
|
||||
return nil
|
||||
}
|
||||
|
||||
// validates terminal block hash in the event of manual overrides before checking for total difficulty.
|
||||
//
|
||||
// def validate_merge_block(block: BeaconBlock) -> None:
|
||||
// """
|
||||
// Check the parent PoW block of execution payload is a valid terminal PoW block.
|
||||
//
|
||||
// Note: Unavailable PoW block(s) may later become available,
|
||||
// and a client software MAY delay a call to ``validate_merge_block``
|
||||
// until the PoW block(s) become available.
|
||||
// """
|
||||
// if TERMINAL_BLOCK_HASH != Hash32():
|
||||
// # If `TERMINAL_BLOCK_HASH` is used as an override, the activation epoch must be reached.
|
||||
// assert compute_epoch_at_slot(block.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
|
||||
// return block.block_hash == TERMINAL_BLOCK_HASH
|
||||
//
|
||||
// pow_block = get_pow_block(block.body.execution_payload.parent_hash)
|
||||
// # Check if `pow_block` is available
|
||||
// assert pow_block is not None
|
||||
// pow_parent = get_pow_block(pow_block.parent_hash)
|
||||
// # Check if `pow_parent` is available
|
||||
// assert pow_parent is not None
|
||||
// # Check if `pow_block` is a valid terminal PoW block
|
||||
// assert is_valid_terminal_pow_block(pow_block, pow_parent)
|
||||
func (s *Service) validateTerminalBlock(b block.SignedBeaconBlock) error {
|
||||
payload, err := b.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bytesutil.ToBytes32(params.BeaconConfig().TerminalBlockHash.Bytes()) != [32]byte{} {
|
||||
// `TERMINAL_BLOCK_HASH` is used as an override, the activation epoch must be reached.
|
||||
if params.BeaconConfig().TerminalBlockHashActivationEpoch > slots.ToEpoch(b.Block().Slot()) {
|
||||
return errors.New("terminal block hash activation epoch not reached")
|
||||
}
|
||||
if !bytes.Equal(payload.ParentHash, params.BeaconConfig().TerminalBlockHash.Bytes()) {
|
||||
return errors.New("parent hash does not match terminal block hash")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
transitionBlk, err := s.cfg.ExecutionEngineCaller.ExecutionBlockByHash(common.BytesToHash(payload.ParentHash))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get transition block")
|
||||
}
|
||||
if transitionBlk == nil {
|
||||
return errors.New("transition block is nil")
|
||||
}
|
||||
parentTransitionBlk, err := s.cfg.ExecutionEngineCaller.ExecutionBlockByHash(common.HexToHash(transitionBlk.ParentHash))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get transition parent block")
|
||||
}
|
||||
if parentTransitionBlk == nil {
|
||||
return errors.New("transition parent block is nil")
|
||||
}
|
||||
transitionBlkTTD, err := uint256.FromHex(transitionBlk.TotalDifficulty)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
transitionParentBlkTTD, err := uint256.FromHex(parentTransitionBlk.TotalDifficulty)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !validTerminalPowBlock(transitionBlkTTD, transitionParentBlkTTD) {
|
||||
return errors.New("invalid difficulty for terminal block")
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": b.Block().Slot(),
|
||||
"transitionBlockHash": common.BytesToHash(payload.ParentHash).String(),
|
||||
"transitionBlockParentHash": common.HexToHash(transitionBlk.ParentHash).String(),
|
||||
"terminalTotalDifficulty": params.BeaconConfig().TerminalTotalDifficulty,
|
||||
"transitionBlockTotalDifficulty": transitionBlkTTD,
|
||||
"transitionBlockParentTotalDifficulty": transitionParentBlkTTD,
|
||||
}).Info("Verified terminal block")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func executionPayloadToExecutableData(payload *enginev1.ExecutionPayload) *catalyst.ExecutableDataV1 {
|
||||
// Convert the base fee bytes from little endian to big endian
|
||||
baseFeeInBigEndian := bytesutil.ReverseByteOrder(payload.BaseFeePerGas)
|
||||
baseFeePerGas := new(big.Int)
|
||||
baseFeePerGas.SetBytes(baseFeeInBigEndian)
|
||||
|
||||
return &catalyst.ExecutableDataV1{
|
||||
BlockHash: common.BytesToHash(payload.BlockHash),
|
||||
ParentHash: common.BytesToHash(payload.ParentHash),
|
||||
FeeRecipient: common.BytesToAddress(payload.FeeRecipient),
|
||||
StateRoot: common.BytesToHash(payload.StateRoot),
|
||||
ReceiptsRoot: common.BytesToHash(payload.ReceiptsRoot),
|
||||
LogsBloom: payload.LogsBloom,
|
||||
Random: common.BytesToHash(payload.Random),
|
||||
Number: payload.BlockNumber,
|
||||
GasLimit: payload.GasLimit,
|
||||
GasUsed: payload.GasUsed,
|
||||
Timestamp: payload.Timestamp,
|
||||
ExtraData: payload.ExtraData,
|
||||
BaseFeePerGas: baseFeePerGas,
|
||||
Transactions: payload.Transactions,
|
||||
}
|
||||
}
|
||||
|
||||
// Saves synced and validated tips to DB.
|
||||
func (s *Service) saveSyncedTipsDB(ctx context.Context) error {
|
||||
tips := s.cfg.ForkChoiceStore.SyncedTips()
|
||||
|
||||
@@ -82,6 +82,8 @@ type config struct {
|
||||
StateGen *stategen.State
|
||||
SlasherAttestationsFeed *event.Feed
|
||||
WeakSubjectivityCheckpt *ethpb.Checkpoint
|
||||
BlockFetcher powchain.POWBlockFetcher
|
||||
ExecutionEngineCaller powchain.ExecutionEngineCaller
|
||||
FinalizedStateAtStartUp state.BeaconState
|
||||
}
|
||||
|
||||
|
||||
@@ -304,3 +304,16 @@ func isEmptyHeader(h *ethpb.ExecutionPayloadHeader) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func EmptyPayload() *enginev1.ExecutionPayload {
|
||||
return &enginev1.ExecutionPayload{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
Random: make([]byte, fieldparams.RootLength),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
|
||||
configureEth1Config(cliCtx)
|
||||
configureNetwork(cliCtx)
|
||||
configureInteropConfig(cliCtx)
|
||||
configureExecutionSetting(cliCtx)
|
||||
|
||||
// Initializes any forks here.
|
||||
params.BeaconConfig().InitializeForkSchedule()
|
||||
@@ -539,6 +540,7 @@ func (b *BeaconNode) registerBlockchainService() error {
|
||||
blockchain.WithDatabase(b.db),
|
||||
blockchain.WithDepositCache(b.depositCache),
|
||||
blockchain.WithChainStartFetcher(web3Service),
|
||||
blockchain.WithExecutionEngineCaller(web3Service),
|
||||
blockchain.WithAttestationPool(b.attestationPool),
|
||||
blockchain.WithExitPool(b.exitPool),
|
||||
blockchain.WithSlashingPool(b.slashingsPool),
|
||||
@@ -765,6 +767,7 @@ func (b *BeaconNode) registerRPCService() error {
|
||||
StateGen: b.stateGen,
|
||||
EnableDebugRPCEndpoints: enableDebugRPCEndpoints,
|
||||
MaxMsgSize: maxMsgSize,
|
||||
ExecutionEngineCaller: web3Service,
|
||||
})
|
||||
|
||||
return b.services.RegisterService(rpcService)
|
||||
|
||||
@@ -6,6 +6,7 @@ go_library(
|
||||
"block_cache.go",
|
||||
"block_reader.go",
|
||||
"deposit.go",
|
||||
"execution_engine.go",
|
||||
"log.go",
|
||||
"log_processing.go",
|
||||
"options.go",
|
||||
@@ -18,6 +19,7 @@ go_library(
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//cmd/beacon-chain:__subpackages__",
|
||||
"//contracts:__subpackages__",
|
||||
"//testing/spectest:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/cache/depositcache:go_default_library",
|
||||
@@ -31,6 +33,7 @@ go_library(
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/state/v1:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//contracts/deposit:go_default_library",
|
||||
@@ -49,6 +52,7 @@ go_library(
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//eth/catalyst:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//ethclient:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//rpc:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
@@ -173,6 +174,28 @@ func (s *Service) BlockByTimestamp(ctx context.Context, time uint64) (*types.Hea
|
||||
return s.findMoreTargetEth1Block(ctx, big.NewInt(int64(estimatedBlk)), time)
|
||||
}
|
||||
|
||||
// BlockByHash returns the pow block by hash.
|
||||
func (s *Service) BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockByHash")
|
||||
defer span.End()
|
||||
|
||||
if s.eth1DataFetcher == nil {
|
||||
return nil, errors.New("nil eth1DataFetcher")
|
||||
}
|
||||
return s.eth1DataFetcher.BlockByHash(ctx, hash)
|
||||
}
|
||||
|
||||
// BlockByNumber returns the pow block by number.
|
||||
func (s *Service) BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.web3service.BlockByNumber")
|
||||
defer span.End()
|
||||
|
||||
if s.eth1DataFetcher == nil {
|
||||
return nil, errors.New("nil eth1DataFetcher")
|
||||
}
|
||||
return s.eth1DataFetcher.BlockByNumber(ctx, number)
|
||||
}
|
||||
|
||||
// Performs a search to find a target eth1 block which is earlier than or equal to the
|
||||
// target time. This method is used when head.time > targetTime
|
||||
func (s *Service) findLessTargetEth1Block(ctx context.Context, startBlk *big.Int, targetTime uint64) (*types.HeaderInfo, error) {
|
||||
|
||||
384
beacon-chain/powchain/execution_engine.go
Normal file
384
beacon-chain/powchain/execution_engine.go
Normal file
@@ -0,0 +1,384 @@
|
||||
package powchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var errNoExecutionEngineConnection = errors.New("can't connect to execution engine")
|
||||
var errInvalidPayload = errors.New("invalid payload")
|
||||
var errSyncing = errors.New("syncing")
|
||||
|
||||
// ExecutionEngineCaller defines methods that wraps around execution engine API calls to enable other prysm services to interact with.
|
||||
type ExecutionEngineCaller interface {
|
||||
// PreparePayload is a wrapper on top of `CatalystClient` to abstract out `types.AssembleBlockParams`.
|
||||
PreparePayload(ctx context.Context, forkchoiceState catalyst.ForkchoiceStateV1, payloadAttributes catalyst.PayloadAttributesV1) (string, error)
|
||||
// GetPayload is a wrapper on top of `CatalystClient`.
|
||||
GetPayload(ctx context.Context, payloadID string) (*catalyst.ExecutableDataV1, error)
|
||||
// NotifyForkChoiceValidated is the wrapper on top of `CatalystClient` to abstract out `types.ConsensusValidatedParams`.
|
||||
NotifyForkChoiceValidated(ctx context.Context, forkchoiceState catalyst.ForkchoiceStateV1) error
|
||||
// ExecutePayload is the wrapper on top of `CatalystClient` to abstract out `types.ForkChoiceParams`.
|
||||
ExecutePayload(ctx context.Context, data *catalyst.ExecutableDataV1) ([]byte, error)
|
||||
// LatestExecutionBlock returns the latest execution block of the pow chain.
|
||||
LatestExecutionBlock() (*ExecutionBlock, error)
|
||||
// ExecutionBlockByHash returns the execution block of a given block hash.
|
||||
ExecutionBlockByHash(blockHash common.Hash) (*ExecutionBlock, error)
|
||||
}
|
||||
|
||||
type EngineRequest struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Method string `json:"method"`
|
||||
Params []interface{} `json:"params"`
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type ErrorRespond struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type GetPayloadRespond struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
ExecutableData *catalyst.ExecutableDataV1 `json:"result"`
|
||||
Id int `json:"id"`
|
||||
Error ErrorRespond `json:"error"`
|
||||
}
|
||||
|
||||
type PreparePayloadRespond struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Result PayloadIDRespond `json:"result"`
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type PayloadIDRespond struct {
|
||||
PayloadID string `json:"payloadId"`
|
||||
}
|
||||
|
||||
type ForkchoiceUpdatedRespond struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Result ForkchoiceUpdatedResult `json:"result"`
|
||||
Id int `json:"id"`
|
||||
Error ErrorRespond `json:"error"`
|
||||
}
|
||||
|
||||
type ForkchoiceUpdatedResult struct {
|
||||
Status string `json:"status"`
|
||||
PayloadID string `json:"payloadId"`
|
||||
}
|
||||
|
||||
type ExecutePayloadRespond struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Result ExecutePayloadResult `json:"result"`
|
||||
Id int `json:"id"`
|
||||
Error ErrorRespond `json:"error"`
|
||||
}
|
||||
|
||||
type ExecutePayloadResult struct {
|
||||
Status string `json:"status"`
|
||||
LatestValidHash string `json:"latestValidHash"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type ExecutionBlockRespond struct {
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Result *ExecutionBlock `json:"result"`
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type ExecutionBlock struct {
|
||||
ParentHash string `json:"parentHash"`
|
||||
Sha3Uncles string `json:"sha3Uncles"`
|
||||
Miner string `json:"miner"`
|
||||
StateRoot string `json:"stateRoot"`
|
||||
TransactionsRoot string `json:"transactionsRoot"`
|
||||
ReceiptsRoot string `json:"receiptsRoot"`
|
||||
LogsBloom string `json:"logsBloom"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
Number string `json:"number"`
|
||||
GasLimit string `json:"gasLimit"`
|
||||
GasUsed string `json:"gasUsed"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
ExtraData string `json:"extraData"`
|
||||
MixHash string `json:"mixHash"`
|
||||
Nonce string `json:"nonce"`
|
||||
TotalDifficulty string `json:"totalDifficulty"`
|
||||
BaseFeePerGas string `json:"baseFeePerGas"`
|
||||
Size string `json:"size"`
|
||||
Hash string `json:"hash"`
|
||||
Transactions []string `json:"transactions"`
|
||||
Uncles []string `json:"uncles"`
|
||||
}
|
||||
|
||||
//GetPayload returns the most recent version of the execution payload that has been built since the corresponding
|
||||
//call to `PreparePayload` method. It returns the `ExecutionPayload` object.
|
||||
//Engine API definition:
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_getpayloadv1
|
||||
func (s *Service) GetPayload(ctx context.Context, payloadID string) (*catalyst.ExecutableDataV1, error) {
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "engine_getPayloadV1",
|
||||
Params: []interface{}{payloadID},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var respond GetPayloadRespond
|
||||
if err := json.Unmarshal(body, &respond); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if respond.Error.Code != 0 {
|
||||
return nil, fmt.Errorf("could not call engine_getPayloadV1, code: %d, message: %s", respond.Error.Code, respond.Error.Message)
|
||||
}
|
||||
|
||||
return respond.ExecutableData, nil
|
||||
}
|
||||
|
||||
// ExecutePayload executes execution payload by calling execution engine.
|
||||
// Engine API definition:
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_executepayloadv1
|
||||
func (s *Service) ExecutePayload(ctx context.Context, data *catalyst.ExecutableDataV1) ([]byte, error) {
|
||||
// TODO: Fix this. Somehow transactions becomes nil with grpc call server->client
|
||||
if data.Transactions == nil {
|
||||
data.Transactions = [][]byte{}
|
||||
}
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "engine_executePayloadV1",
|
||||
Params: []interface{}{data},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var respond ExecutePayloadRespond
|
||||
if err := json.Unmarshal(body, &respond); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if respond.Error.Code != 0 {
|
||||
return nil, fmt.Errorf("could not call engine_executePayloadV1, code: %d, message: %s", respond.Error.Code, respond.Error.Message)
|
||||
}
|
||||
|
||||
if respond.Result.Status == catalyst.INVALID.Status {
|
||||
return common.FromHex(respond.Result.LatestValidHash), errInvalidPayload
|
||||
}
|
||||
if respond.Result.Status == catalyst.SYNCING.Status {
|
||||
return common.FromHex(respond.Result.LatestValidHash), errSyncing
|
||||
}
|
||||
|
||||
return common.FromHex(respond.Result.LatestValidHash), nil
|
||||
}
|
||||
|
||||
// NotifyForkChoiceValidated notifies execution engine on fork choice updates.
|
||||
// Engine API definition:
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_forkchoiceupdatedv1
|
||||
func (s *Service) NotifyForkChoiceValidated(ctx context.Context, forkchoiceState catalyst.ForkchoiceStateV1) error {
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "engine_forkchoiceUpdatedV1",
|
||||
Params: []interface{}{forkchoiceState, nil},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequest("POST", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var respond ForkchoiceUpdatedRespond
|
||||
if err := json.Unmarshal(body, &respond); err != nil {
|
||||
return err
|
||||
}
|
||||
if respond.Error.Code != 0 {
|
||||
return fmt.Errorf("could not call engine_forkchoiceUpdatedV1, code: %d, message: %s", respond.Error.Code, respond.Error.Message)
|
||||
}
|
||||
if respond.Result.Status == catalyst.SYNCING.Status {
|
||||
return errSyncing
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreparePayload signals execution engine to prepare execution payload along with the latest fork choice state.
|
||||
// It reuses `engine_forkchoiceUpdatedV1` end point to prepare payload.
|
||||
// Engine API definition:
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_forkchoiceupdatedv1
|
||||
func (s *Service) PreparePayload(ctx context.Context, forkchoiceState catalyst.ForkchoiceStateV1, payloadAttributes catalyst.PayloadAttributesV1) (string, error) {
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "engine_forkchoiceUpdatedV1",
|
||||
Params: []interface{}{forkchoiceState, payloadAttributes},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req, err := http.NewRequest("POST", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var respond ForkchoiceUpdatedRespond
|
||||
if err := json.Unmarshal(body, &respond); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if respond.Error.Code != 0 {
|
||||
return "", fmt.Errorf("could not call engine_forkchoiceUpdatedV1, code: %d, message: %s", respond.Error.Code, respond.Error.Message)
|
||||
}
|
||||
if respond.Result.Status == catalyst.SYNCING.Status {
|
||||
return "", errSyncing
|
||||
}
|
||||
|
||||
return respond.Result.PayloadID, nil
|
||||
}
|
||||
|
||||
func (s *Service) LatestExecutionBlock() (*ExecutionBlock, error) {
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "eth_getBlockByNumber",
|
||||
Params: []interface{}{"latest", false},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest("GET", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data ExecutionBlockRespond
|
||||
if err := json.Unmarshal(body, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data.Result, nil
|
||||
}
|
||||
|
||||
func (s *Service) ExecutionBlockByHash(blockHash common.Hash) (*ExecutionBlock, error) {
|
||||
reqBody := &EngineRequest{
|
||||
JsonRPC: "2.0",
|
||||
Method: "eth_getBlockByHash",
|
||||
Params: []interface{}{blockHash.String(), false},
|
||||
}
|
||||
enc, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest("GET", s.cfg.currHttpEndpoint.Url, bytes.NewBuffer(enc))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data ExecutionBlockRespond
|
||||
if err := json.Unmarshal(body, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data.Result, nil
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||
"github.com/prysmaticlabs/prysm/config/features"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/container/trie"
|
||||
contracts "github.com/prysmaticlabs/prysm/contracts/deposit"
|
||||
@@ -101,6 +102,8 @@ type POWBlockFetcher interface {
|
||||
BlockHashByHeight(ctx context.Context, height *big.Int) (common.Hash, error)
|
||||
BlockExists(ctx context.Context, hash common.Hash) (bool, *big.Int, error)
|
||||
BlockExistsWithCache(ctx context.Context, hash common.Hash) (bool, *big.Int, error)
|
||||
BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error)
|
||||
BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error)
|
||||
}
|
||||
|
||||
// Chain defines a standard interface for the powchain service in Prysm.
|
||||
@@ -116,6 +119,8 @@ type RPCDataFetcher interface {
|
||||
HeaderByNumber(ctx context.Context, number *big.Int) (*gethTypes.Header, error)
|
||||
HeaderByHash(ctx context.Context, hash common.Hash) (*gethTypes.Header, error)
|
||||
SyncProgress(ctx context.Context) (*ethereum.SyncProgress, error)
|
||||
BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error)
|
||||
BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error)
|
||||
}
|
||||
|
||||
// RPCClient defines the rpc methods required to interact with the eth1 node.
|
||||
@@ -783,12 +788,14 @@ func (s *Service) initPOWService() {
|
||||
s.latestEth1Data.BlockHeight = header.Number.Uint64()
|
||||
s.latestEth1Data.BlockHash = header.Hash().Bytes()
|
||||
s.latestEth1Data.BlockTime = header.Time
|
||||
|
||||
if err := s.processPastLogs(ctx); err != nil {
|
||||
log.Errorf("Unable to process past logs %v", err)
|
||||
s.retryETH1Node(err)
|
||||
continue
|
||||
if !features.Get().KintsugiTestnet {
|
||||
if err := s.processPastLogs(ctx); err != nil {
|
||||
log.Errorf("Unable to process past logs %v", err)
|
||||
s.retryETH1Node(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Cache eth1 headers from our voting period.
|
||||
if err := s.cacheHeadersForEth1DataVote(ctx); err != nil {
|
||||
log.Errorf("Unable to process past headers %v", err)
|
||||
@@ -797,7 +804,7 @@ func (s *Service) initPOWService() {
|
||||
}
|
||||
// Handle edge case with embedded genesis state by fetching genesis header to determine
|
||||
// its height.
|
||||
if s.chainStartData.Chainstarted && s.chainStartData.GenesisBlock == 0 {
|
||||
if s.chainStartData.Chainstarted && s.chainStartData.GenesisBlock == 0 && !features.Get().KintsugiTestnet {
|
||||
genHeader, err := s.eth1DataFetcher.HeaderByHash(ctx, common.BytesToHash(s.chainStartData.Eth1Data.BlockHash))
|
||||
if err != nil {
|
||||
log.Errorf("Unable to retrieve genesis ETH1.0 chain header: %v", err)
|
||||
|
||||
@@ -81,6 +81,16 @@ type goodFetcher struct {
|
||||
backend *backends.SimulatedBackend
|
||||
}
|
||||
|
||||
// BlockByHash is a stub for `goodFetcher`.
|
||||
func (g *goodFetcher) BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// BlockByNumber is a stub for `goodFetcher`.
|
||||
func (g *goodFetcher) BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (g *goodFetcher) HeaderByHash(_ context.Context, hash common.Hash) (*gethTypes.Header, error) {
|
||||
if bytes.Equal(hash.Bytes(), common.BytesToHash([]byte{0}).Bytes()) {
|
||||
return nil, fmt.Errorf("expected block hash to be nonzero %v", hash)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/prysmaticlabs/prysm/async/event"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
@@ -59,6 +60,16 @@ func (_ *FaultyMockPOWChain) DepositRoot() [32]byte {
|
||||
return [32]byte{}
|
||||
}
|
||||
|
||||
// BlockByHash is a stub for `FaultyMockPOWChain`.
|
||||
func (m *FaultyMockPOWChain) BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// BlockByNumber is a stub for `FaultyMockPOWChain`.
|
||||
func (m *FaultyMockPOWChain) BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// DepositTrie --
|
||||
func (_ *FaultyMockPOWChain) DepositTrie() *trie.SparseMerkleTrie {
|
||||
return &trie.SparseMerkleTrie{}
|
||||
|
||||
@@ -37,6 +37,16 @@ type POWChain struct {
|
||||
Errors []error
|
||||
}
|
||||
|
||||
// BlockByHash is a stub for `POWChain`.
|
||||
func (m *POWChain) BlockByHash(ctx context.Context, hash common.Hash) (*gethTypes.Block, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// BlockByNumber is a stub for `POWChain`.
|
||||
func (m *POWChain) BlockByNumber(ctx context.Context, number *big.Int) (*gethTypes.Block, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// GenesisTime represents a static past date - JAN 01 2000.
|
||||
var GenesisTime = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ go_test(
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
|
||||
"@com_github_holiman_uint256//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@com_github_wealdtech_go_bytesutil//:go_default_library",
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/holiman/uint256"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
@@ -52,7 +53,6 @@ func TestGetSpec(t *testing.T) {
|
||||
config.BellatrixForkEpoch = 101
|
||||
config.ShardingForkVersion = []byte("ShardingForkVersion")
|
||||
config.ShardingForkEpoch = 102
|
||||
config.MinAnchorPowBlockDifficulty = 1000
|
||||
config.BLSWithdrawalPrefixByte = byte('b')
|
||||
config.GenesisDelay = 24
|
||||
config.SecondsPerSlot = 25
|
||||
@@ -100,7 +100,7 @@ func TestGetSpec(t *testing.T) {
|
||||
config.MinSyncCommitteeParticipants = 71
|
||||
config.TerminalBlockHash = common.HexToHash("TerminalBlockHash")
|
||||
config.TerminalBlockHashActivationEpoch = 72
|
||||
config.TerminalTotalDifficulty = 73
|
||||
config.TerminalTotalDifficulty = uint256.NewInt(73)
|
||||
config.FeeRecipient = common.HexToAddress("FeeRecipient")
|
||||
|
||||
var dbp [4]byte
|
||||
|
||||
@@ -14,6 +14,7 @@ go_library(
|
||||
"proposer_attestations.go",
|
||||
"proposer_deposits.go",
|
||||
"proposer_eth1data.go",
|
||||
"proposer_execution_payload.go",
|
||||
"proposer_phase0.go",
|
||||
"proposer_sync_aggregate.go",
|
||||
"server.go",
|
||||
@@ -39,6 +40,7 @@ go_library(
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
"//beacon-chain/core/transition/interop:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/operations/attestations:go_default_library",
|
||||
"//beacon-chain/operations/slashings:go_default_library",
|
||||
"//beacon-chain/operations/synccommittee:go_default_library",
|
||||
@@ -59,6 +61,7 @@ go_library(
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation/aggregation:go_default_library",
|
||||
@@ -69,6 +72,8 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//time:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//eth/catalyst:go_default_library",
|
||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
blockfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/block"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition/interop"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
@@ -34,18 +35,27 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.GetBeaconBlock")
|
||||
defer span.End()
|
||||
span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot)))
|
||||
|
||||
if slots.ToEpoch(req.Slot) < params.BeaconConfig().AltairForkEpoch {
|
||||
blk, err := vs.getPhase0BeaconBlock(ctx, req)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not fetch phase0 beacon block: %v", err)
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: blk}}, nil
|
||||
} else if slots.ToEpoch(req.Slot) < params.BeaconConfig().BellatrixForkEpoch {
|
||||
blk, err := vs.getAltairBeaconBlock(ctx, req)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not fetch Altair beacon block: %v", err)
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: blk}}, nil
|
||||
}
|
||||
blk, err := vs.getAltairBeaconBlock(ctx, req)
|
||||
|
||||
blk, err := vs.getBellatrixBeaconBlock(ctx, req)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not fetch Altair beacon block: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "Could not fetch Bellatrix beacon block: %v", err)
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: blk}}, nil
|
||||
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: blk}}, nil
|
||||
}
|
||||
|
||||
// GetBlock is called by a proposer during its assigned slot to request a block to sign
|
||||
@@ -60,6 +70,99 @@ func (vs *Server) GetBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb
|
||||
return vs.getPhase0BeaconBlock(ctx, req)
|
||||
}
|
||||
|
||||
func (vs *Server) getBellatrixBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockBellatrix, error) {
|
||||
altairBlk, err := vs.buildAltairBeaconBlock(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
payload, err := vs.getExecutionPayload(ctx, req.Slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get execution payload")
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"blockNumber": payload.BlockNumber,
|
||||
"blockHash": fmt.Sprintf("%#x", payload.BlockHash),
|
||||
"parentHash": fmt.Sprintf("%#x", payload.ParentHash),
|
||||
"coinBase": fmt.Sprintf("%#x", payload.FeeRecipient),
|
||||
"gasLimit": payload.GasLimit,
|
||||
"gasUsed": payload.GasUsed,
|
||||
"baseFeePerGas": payload.BaseFeePerGas,
|
||||
"random": fmt.Sprintf("%#x", payload.Random),
|
||||
"extraData": fmt.Sprintf("%#x", payload.ExtraData),
|
||||
"txs": payload.Transactions,
|
||||
}).Info("Retrieved payload")
|
||||
|
||||
blk := ðpb.BeaconBlockBellatrix{
|
||||
Slot: altairBlk.Slot,
|
||||
ProposerIndex: altairBlk.ProposerIndex,
|
||||
ParentRoot: altairBlk.ParentRoot,
|
||||
StateRoot: params.BeaconConfig().ZeroHash[:],
|
||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: altairBlk.Body.RandaoReveal,
|
||||
Eth1Data: altairBlk.Body.Eth1Data,
|
||||
Graffiti: altairBlk.Body.Graffiti,
|
||||
ProposerSlashings: altairBlk.Body.ProposerSlashings,
|
||||
AttesterSlashings: altairBlk.Body.AttesterSlashings,
|
||||
Attestations: altairBlk.Body.Attestations,
|
||||
Deposits: altairBlk.Body.Deposits,
|
||||
VoluntaryExits: altairBlk.Body.VoluntaryExits,
|
||||
SyncAggregate: altairBlk.Body.SyncAggregate,
|
||||
ExecutionPayload: payload,
|
||||
},
|
||||
}
|
||||
// Compute state root with the newly constructed block.
|
||||
wsb, err := wrapper.WrappedBellatrixSignedBeaconBlock(
|
||||
ðpb.SignedBeaconBlockBellatrix{Block: blk, Signature: make([]byte, 96)},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stateRoot, err := vs.computeStateRoot(ctx, wsb)
|
||||
if err != nil {
|
||||
interop.WriteBlockToDisk(wsb, true /*failed*/)
|
||||
return nil, fmt.Errorf("could not compute state root: %v", err)
|
||||
}
|
||||
blk.StateRoot = stateRoot
|
||||
return blk, nil
|
||||
}
|
||||
|
||||
func (vs *Server) buildAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.buildAltairBeaconBlock")
|
||||
defer span.End()
|
||||
blkData, err := vs.buildPhase0BlockData(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not build block data: %v", err)
|
||||
}
|
||||
// Use zero hash as stub for state root to compute later.
|
||||
stateRoot := params.BeaconConfig().ZeroHash[:]
|
||||
|
||||
// No need for safe sub as req.Slot cannot be 0 if requesting Altair blocks. If 0, we will be throwing
|
||||
// an error in the first validity check of this endpoint.
|
||||
syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(blkData.ParentRoot))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ðpb.BeaconBlockAltair{
|
||||
Slot: req.Slot,
|
||||
ParentRoot: blkData.ParentRoot,
|
||||
StateRoot: stateRoot,
|
||||
ProposerIndex: blkData.ProposerIdx,
|
||||
Body: ðpb.BeaconBlockBodyAltair{
|
||||
Eth1Data: blkData.Eth1Data,
|
||||
Deposits: blkData.Deposits,
|
||||
Attestations: blkData.Attestations,
|
||||
RandaoReveal: req.RandaoReveal,
|
||||
ProposerSlashings: blkData.ProposerSlashings,
|
||||
AttesterSlashings: blkData.AttesterSlashings,
|
||||
VoluntaryExits: blkData.VoluntaryExits,
|
||||
Graffiti: blkData.Graffiti[:],
|
||||
SyncAggregate: syncAggregate,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ProposeBeaconBlock is called by a proposer during its assigned slot to create a block in an attempt
|
||||
// to get it processed by the beacon node as the canonical head.
|
||||
func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) {
|
||||
@@ -75,6 +178,11 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not wrap altair beacon block")
|
||||
}
|
||||
case *ethpb.GenericSignedBeaconBlock_Bellatrix:
|
||||
blk, err = wrapper.WrappedBellatrixSignedBeaconBlock(b.Bellatrix)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not wrap Bellatrix beacon block")
|
||||
}
|
||||
default:
|
||||
return nil, status.Error(codes.Internal, "block version not supported")
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
|
||||
switch st.Version() {
|
||||
case version.Phase0:
|
||||
attestationProcessor = blocks.ProcessAttestationNoVerifySignature
|
||||
case version.Altair:
|
||||
case version.Altair, version.Bellatrix:
|
||||
// Use a wrapper here, as go needs strong typing for the function signature.
|
||||
attestationProcessor = func(ctx context.Context, st state.BeaconState, attestation *ethpb.Attestation) (state.BeaconState, error) {
|
||||
totalBalance, err := helpers.TotalActiveBalance(st)
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// This returns the execution payload of a given slot. The function has full awareness of pre and post merge.
|
||||
// Payload is computed given the respected time of merge.
|
||||
//
|
||||
// Spec code:
|
||||
// def prepare_execution_payload(state: BeaconState,
|
||||
// pow_chain: Dict[Hash32, PowBlock],
|
||||
// finalized_block_hash: Hash32,
|
||||
// fee_recipient: ExecutionAddress,
|
||||
// execution_engine: ExecutionEngine) -> Optional[PayloadId]:
|
||||
// if not is_merge_complete(state):
|
||||
// is_terminal_block_hash_set = TERMINAL_BLOCK_HASH != Hash32()
|
||||
// is_activation_epoch_reached = get_current_epoch(state.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
|
||||
// if is_terminal_block_hash_set and not is_activation_epoch_reached:
|
||||
// # Terminal block hash is set but activation epoch is not yet reached, no prepare payload call is needed
|
||||
// return None
|
||||
//
|
||||
// terminal_pow_block = get_terminal_pow_block(pow_chain)
|
||||
// if terminal_pow_block is None:
|
||||
// # Pre-merge, no prepare payload call is needed
|
||||
// return None
|
||||
// # Signify merge via producing on top of the terminal PoW block
|
||||
// parent_hash = terminal_pow_block.block_hash
|
||||
// else:
|
||||
// # Post-merge, normal payload
|
||||
// parent_hash = state.latest_execution_payload_header.block_hash
|
||||
//
|
||||
// # Set the forkchoice head and initiate the payload build process
|
||||
// payload_attributes = PayloadAttributes(
|
||||
// timestamp=compute_timestamp_at_slot(state, state.slot),
|
||||
// random=get_randao_mix(state, get_current_epoch(state)),
|
||||
// fee_recipient=fee_recipient,
|
||||
// )
|
||||
// return execution_engine.notify_forkchoice_updated(parent_hash, finalized_block_hash, payload_attributes)
|
||||
func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot) (*enginev1.ExecutionPayload, error) {
|
||||
// TODO_MERGE: Reuse the same head state as in building phase0 block attestation.
|
||||
st, err := vs.HeadFetcher.HeadState(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
st, err = transition.ProcessSlots(ctx, st, slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var parentHash []byte
|
||||
var hasTerminalBlock bool
|
||||
complete, err := blocks.MergeTransitionComplete(st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !complete {
|
||||
if bytesutil.ToBytes32(params.BeaconConfig().TerminalBlockHash.Bytes()) != [32]byte{} {
|
||||
// `TERMINAL_BLOCK_HASH` is used as an override, the activation epoch must be reached.
|
||||
isActivationEpochReached := params.BeaconConfig().TerminalBlockHashActivationEpoch <= slots.ToEpoch(slot)
|
||||
if !isActivationEpochReached {
|
||||
return blocks.EmptyPayload(), nil
|
||||
}
|
||||
}
|
||||
|
||||
parentHash, hasTerminalBlock, err = vs.getTerminalBlockHash(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !hasTerminalBlock {
|
||||
// No terminal block signals this is pre merge, empty payload is used.
|
||||
return blocks.EmptyPayload(), nil
|
||||
}
|
||||
// Terminal block found signals production on top of terminal PoW block.
|
||||
} else {
|
||||
// Post merge, normal payload is used.
|
||||
header, err := st.LatestExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parentHash = header.BlockHash
|
||||
}
|
||||
|
||||
t, err := slots.ToTime(st.GenesisTime(), slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
random, err := helpers.RandaoMix(st, time.CurrentEpoch(st))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
finalizedBlock, err := vs.BeaconDB.Block(ctx, bytesutil.ToBytes32(st.FinalizedCheckpoint().Root))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalizedBlockHash := params.BeaconConfig().ZeroHash[:]
|
||||
if finalizedBlock != nil && finalizedBlock.Version() == version.Bellatrix {
|
||||
finalizedPayload, err := finalizedBlock.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalizedBlockHash = finalizedPayload.BlockHash
|
||||
}
|
||||
|
||||
f := catalyst.ForkchoiceStateV1{
|
||||
HeadBlockHash: common.BytesToHash(parentHash),
|
||||
SafeBlockHash: common.BytesToHash(parentHash),
|
||||
FinalizedBlockHash: common.BytesToHash(finalizedBlockHash),
|
||||
}
|
||||
p := catalyst.PayloadAttributesV1{
|
||||
Timestamp: uint64(t.Unix()),
|
||||
Random: common.BytesToHash(random),
|
||||
SuggestedFeeRecipient: params.BeaconConfig().FeeRecipient,
|
||||
}
|
||||
id, err := vs.ExecutionEngineCaller.PreparePayload(ctx, f, p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not prepare payload")
|
||||
}
|
||||
data, err := vs.ExecutionEngineCaller.GetPayload(ctx, id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get payload")
|
||||
}
|
||||
|
||||
return executableDataToExecutionPayload(data), nil
|
||||
}
|
||||
|
||||
func executableDataToExecutionPayload(ed *catalyst.ExecutableDataV1) *enginev1.ExecutionPayload {
|
||||
return &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo(ed.ParentHash.Bytes(), 32),
|
||||
FeeRecipient: bytesutil.PadTo(ed.FeeRecipient.Bytes(), 20),
|
||||
StateRoot: bytesutil.PadTo(ed.StateRoot.Bytes(), 32),
|
||||
ReceiptsRoot: bytesutil.PadTo(ed.ReceiptsRoot.Bytes(), 32),
|
||||
LogsBloom: bytesutil.PadTo(ed.LogsBloom, 256),
|
||||
Random: bytesutil.PadTo(ed.Random.Bytes(), 32),
|
||||
BlockNumber: ed.Number,
|
||||
GasLimit: ed.GasLimit,
|
||||
GasUsed: ed.GasUsed,
|
||||
Timestamp: ed.Timestamp,
|
||||
ExtraData: ed.ExtraData,
|
||||
BaseFeePerGas: bytesutil.PadTo(ed.BaseFeePerGas.Bytes(), 32),
|
||||
BlockHash: bytesutil.PadTo(ed.BlockHash.Bytes(), 32),
|
||||
Transactions: ed.Transactions,
|
||||
}
|
||||
}
|
||||
|
||||
// This returns the valid terminal block hash with an existence bool value.
|
||||
//
|
||||
// Spec code:
|
||||
// def get_terminal_pow_block(pow_chain: Dict[Hash32, PowBlock]) -> Optional[PowBlock]:
|
||||
// if TERMINAL_BLOCK_HASH != Hash32():
|
||||
// # Terminal block hash override takes precedence over terminal total difficulty
|
||||
// if TERMINAL_BLOCK_HASH in pow_chain:
|
||||
// return pow_chain[TERMINAL_BLOCK_HASH]
|
||||
// else:
|
||||
// return None
|
||||
//
|
||||
// return get_pow_block_at_terminal_total_difficulty(pow_chain)
|
||||
func (vs *Server) getTerminalBlockHash(ctx context.Context) ([]byte, bool, error) {
|
||||
terminalBlockHash := params.BeaconConfig().TerminalBlockHash
|
||||
// Terminal block hash override takes precedence over terminal total difficult.
|
||||
if params.BeaconConfig().TerminalBlockHash != params.BeaconConfig().ZeroHash {
|
||||
e, _, err := vs.Eth1BlockFetcher.BlockExists(ctx, terminalBlockHash)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !e {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return terminalBlockHash.Bytes(), true, nil
|
||||
}
|
||||
|
||||
return vs.getPowBlockHashAtTerminalTotalDifficulty(ctx)
|
||||
}
|
||||
|
||||
// This returns the valid terminal block hash based on total difficulty.
|
||||
//
|
||||
// Spec code:
|
||||
// def get_pow_block_at_terminal_total_difficulty(pow_chain: Dict[Hash32, PowBlock]) -> Optional[PowBlock]:
|
||||
// # `pow_chain` abstractly represents all blocks in the PoW chain
|
||||
// for block in pow_chain:
|
||||
// parent = pow_chain[block.parent_hash]
|
||||
// block_reached_ttd = block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
|
||||
// parent_reached_ttd = parent.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
|
||||
// if block_reached_ttd and not parent_reached_ttd:
|
||||
// return block
|
||||
//
|
||||
// return None
|
||||
func (vs *Server) getPowBlockHashAtTerminalTotalDifficulty(ctx context.Context) ([]byte, bool, error) {
|
||||
blk, err := vs.ExecutionEngineCaller.LatestExecutionBlock()
|
||||
if err != nil {
|
||||
return nil, false, errors.Wrap(err, "could not get latest execution block")
|
||||
}
|
||||
parentBlk, err := vs.ExecutionEngineCaller.ExecutionBlockByHash(common.HexToHash(blk.ParentHash))
|
||||
if err != nil {
|
||||
return nil, false, errors.Wrap(err, "could not get parent execution block")
|
||||
}
|
||||
if parentBlk == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
terminalTotalDifficulty := params.BeaconConfig().TerminalTotalDifficulty.ToBig()
|
||||
currentTotalDifficulty := common.HexToHash(blk.TotalDifficulty).Big()
|
||||
parentTotalDifficulty := common.HexToHash(parentBlk.TotalDifficulty).Big()
|
||||
blkNumber := blk.Number
|
||||
// TODO_MERGE: This can theoretically loop indefinitely. More discussion: https://github.com/ethereum/consensus-specs/issues/2636
|
||||
logged := false
|
||||
for {
|
||||
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
||||
parentReachedTTD := terminalTotalDifficulty.Cmp(parentTotalDifficulty) >= 0
|
||||
|
||||
if blockReachedTTD && parentReachedTTD {
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentTotalDifficulty": currentTotalDifficulty,
|
||||
"parentTotalDifficulty": parentTotalDifficulty,
|
||||
"terminalTotalDifficulty": terminalTotalDifficulty,
|
||||
"terminalBlockHash": fmt.Sprintf("%#x", common.HexToHash(blk.Hash)),
|
||||
"terminalBlockNumber": blkNumber,
|
||||
}).Info("'Terminal difficulty reached")
|
||||
return common.HexToHash(blk.Hash).Bytes(), true, err
|
||||
} else {
|
||||
if !logged {
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentTotalDifficulty": currentTotalDifficulty,
|
||||
"parentTotalDifficulty": parentTotalDifficulty,
|
||||
"terminalTotalDifficulty": terminalTotalDifficulty,
|
||||
"terminalBlockHash": fmt.Sprintf("%#x", common.HexToHash(blk.Hash)),
|
||||
"terminalBlockNumber": blkNumber,
|
||||
}).Info("Terminal difficulty NOT reached")
|
||||
logged = true
|
||||
}
|
||||
|
||||
blk := parentBlk
|
||||
blkNumber = blk.Number
|
||||
// TODO_MERGE: Add pow block cache to avoid requesting seen block.
|
||||
|
||||
parentBlk, err = vs.ExecutionEngineCaller.ExecutionBlockByHash(common.HexToHash(blk.ParentHash))
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if parentBlk == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
currentTotalDifficulty = common.HexToHash(blk.TotalDifficulty).Big()
|
||||
parentTotalDifficulty = common.HexToHash(parentBlk.TotalDifficulty).Big()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
|
||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/operations/synccommittee"
|
||||
@@ -62,6 +63,8 @@ type Server struct {
|
||||
PendingDepositsFetcher depositcache.PendingDepositsFetcher
|
||||
OperationNotifier opfeed.Notifier
|
||||
StateGen stategen.StateManager
|
||||
ExecutionEngineCaller powchain.ExecutionEngineCaller
|
||||
BeaconDB db.HeadAccessDatabase
|
||||
}
|
||||
|
||||
// WaitForActivation checks if a validator public key exists in the active validator registry of the current
|
||||
|
||||
@@ -108,6 +108,7 @@ type Config struct {
|
||||
OperationNotifier opfeed.Notifier
|
||||
StateGen *stategen.State
|
||||
MaxMsgSize int
|
||||
ExecutionEngineCaller powchain.ExecutionEngineCaller
|
||||
}
|
||||
|
||||
// NewService instantiates a new RPC service instance that will
|
||||
@@ -192,6 +193,8 @@ func (s *Service) Start() {
|
||||
SlashingsPool: s.cfg.SlashingsPool,
|
||||
StateGen: s.cfg.StateGen,
|
||||
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
|
||||
ExecutionEngineCaller: s.cfg.ExecutionEngineCaller,
|
||||
BeaconDB: s.cfg.BeaconDB,
|
||||
}
|
||||
validatorServerV1 := &validator.Server{
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 6de36f732d72b5c4c0c967bc0edcc752b7afdd337e829486954eb6affda84da8
|
||||
// Hash: 2e923b42b8e4fcc278301da6506b212334a78169cb32c70e0d66a636435b8925
|
||||
package v1
|
||||
|
||||
import (
|
||||
|
||||
2
beacon-chain/state/state-native/v2/generated.ssz.go
Executable file → Normal file
2
beacon-chain/state/state-native/v2/generated.ssz.go
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 6a7886393e8874ccf57ea6c160647da09f5e541234a235ee71f3bf786d56a100
|
||||
// Hash: ec98b14e43fd11e74e0d9e705a7afe74a77706c3e215d7940b11411859873f4b
|
||||
package v2
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: a71c6e70ae416774612961057f4c96b97b5c3323270a80167d30ea672ea2f5cd
|
||||
// Hash: aa2156293aac4326afe2b8c0ba985a0291c83f20c8d8b92d148bc810a7f442e9
|
||||
package v3
|
||||
|
||||
import (
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
// computeFieldRoots returns the hash tree root computations of every field in
|
||||
// the beacon state as a list of 32 byte roots.
|
||||
//nolint:deadcode
|
||||
func computeFieldRoots(ctx context.Context, state *ethpb.BeaconStateBellatrix) ([][]byte, error) {
|
||||
if features.Get().EnableSSZCache {
|
||||
return stateutil.CachedHasher.ComputeFieldRootsWithHasherBellatrix(ctx, state)
|
||||
|
||||
@@ -151,7 +151,8 @@ func (s *Service) processPendingBlocks(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.validateBeaconBlock(ctx, b, blkRoot); err != nil {
|
||||
genesisTime := uint64(s.cfg.chain.GenesisTime().Unix())
|
||||
if err := s.validateBeaconBlock(ctx, b, blkRoot, genesisTime); err != nil {
|
||||
log.Debugf("Could not validate block from slot %d: %v", b.Block().Slot(), err)
|
||||
s.setBadBlock(ctx, blkRoot)
|
||||
tracing.AnnotateError(span, err)
|
||||
|
||||
@@ -161,7 +161,7 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
|
||||
return pubsub.ValidationIgnore, errors.Errorf("unknown parent for block with slot %d and parent root %#x", blk.Block().Slot(), blk.Block().ParentRoot())
|
||||
}
|
||||
|
||||
if err := s.validateBeaconBlock(ctx, blk, blockRoot); err != nil {
|
||||
if err := s.validateBeaconBlock(ctx, blk, blockRoot, genesisTime); err != nil {
|
||||
return pubsub.ValidationReject, err
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
|
||||
return pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
func (s *Service) validateBeaconBlock(ctx context.Context, blk block.SignedBeaconBlock, blockRoot [32]byte) error {
|
||||
func (s *Service) validateBeaconBlock(ctx context.Context, blk block.SignedBeaconBlock, blockRoot [32]byte, genesisTime uint64) error {
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateBeaconBlock")
|
||||
defer span.End()
|
||||
|
||||
|
||||
@@ -122,7 +122,6 @@ var appHelpFlagGroups = []flagGroup{
|
||||
flags.WeakSubjectivityCheckpt,
|
||||
flags.Eth1HeaderReqLimit,
|
||||
flags.GenesisStatePath,
|
||||
flags.MinPeersPerSubnet,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -36,7 +36,8 @@ const disabledFeatureFlag = "Disabled feature flag"
|
||||
// Flags is a struct to represent which features the client will perform on runtime.
|
||||
type Flags struct {
|
||||
// Testnet Flags.
|
||||
PyrmontTestnet bool // PyrmontTestnet defines the flag through which we can enable the node to run on the Pyrmont testnet.
|
||||
PyrmontTestnet bool // PyrmontTestnet defines the flag through which we can enable the node to run on the Pyrmont testnet.
|
||||
KintsugiTestnet bool // KintsugiTestnet defines the flag through which we can enable node to run on the merge testnet.
|
||||
|
||||
// Feature related flags.
|
||||
RemoteSlasherProtection bool // RemoteSlasherProtection utilizes a beacon node with --slasher mode for validator slashing protection.
|
||||
@@ -128,6 +129,11 @@ func configureTestnet(ctx *cli.Context, cfg *Flags) {
|
||||
log.Warn("Running on the Prater Testnet")
|
||||
params.UsePraterConfig()
|
||||
params.UsePraterNetworkConfig()
|
||||
} else if ctx.Bool(KintsugiTestnet.Name) {
|
||||
log.Warn("Running on the Merge Testnet")
|
||||
params.UseMergeTestConfig()
|
||||
params.UseMergeTestNetworkConfig()
|
||||
cfg.KintsugiTestnet = true
|
||||
} else {
|
||||
log.Warn("Running on Ethereum Consensus Mainnet")
|
||||
params.UseMainnetConfig()
|
||||
|
||||
@@ -17,6 +17,11 @@ var (
|
||||
Name: "prater",
|
||||
Usage: "Run Prysm configured for the Prater test network",
|
||||
}
|
||||
// KintsugiTestnet flag for the multiclient Ethereum consensus testnet.
|
||||
KintsugiTestnet = &cli.BoolFlag{
|
||||
Name: "kintsugi-testnet",
|
||||
Usage: "Run Prysm configured for the Kintsugi test network",
|
||||
}
|
||||
// Mainnet flag for easier tooling, no-op
|
||||
Mainnet = &cli.BoolFlag{
|
||||
Value: true,
|
||||
@@ -144,6 +149,7 @@ var ValidatorFlags = append(deprecatedFlags, []cli.Flag{
|
||||
disableAttestingHistoryDBCache,
|
||||
PyrmontTestnet,
|
||||
PraterTestnet,
|
||||
KintsugiTestnet,
|
||||
Mainnet,
|
||||
dynamicKeyReloadDebounceInterval,
|
||||
attestTimely,
|
||||
@@ -163,6 +169,7 @@ var BeaconChainFlags = append(deprecatedFlags, []cli.Flag{
|
||||
disableGRPCConnectionLogging,
|
||||
PyrmontTestnet,
|
||||
PraterTestnet,
|
||||
KintsugiTestnet,
|
||||
Mainnet,
|
||||
enablePeerScorer,
|
||||
enableLargerGossipHistory,
|
||||
|
||||
@@ -12,6 +12,7 @@ go_library(
|
||||
"minimal_config.go",
|
||||
"network_config.go",
|
||||
"testnet_e2e_config.go",
|
||||
"testnet_kintsugi_config.go",
|
||||
"testnet_prater_config.go",
|
||||
"testnet_pyrmont_config.go",
|
||||
"testutils.go",
|
||||
@@ -24,6 +25,7 @@ go_library(
|
||||
"//math:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//params:go_default_library",
|
||||
"@com_github_holiman_uint256//:go_default_library",
|
||||
"@com_github_mohae_deepcopy//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/holiman/uint256"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
)
|
||||
@@ -173,7 +174,7 @@ type BeaconChainConfig struct {
|
||||
InactivityScoreRecoveryRate uint64 `yaml:"INACTIVITY_SCORE_RECOVERY_RATE" spec:"true"` // InactivityScoreRecoveryRate for recovering score bias penalties during inactivity.
|
||||
EpochsPerSyncCommitteePeriod types.Epoch `yaml:"EPOCHS_PER_SYNC_COMMITTEE_PERIOD" spec:"true"` // EpochsPerSyncCommitteePeriod defines how many epochs per sync committee period.
|
||||
|
||||
// Updated penalty values. This moves penalty parameters toward their final, maximum security values.
|
||||
// Updated Altair penalty values. This moves penalty parameters toward their final, maximum security values.
|
||||
// Note: We do not override previous configuration values but instead creates new values and replaces usage throughout.
|
||||
InactivityPenaltyQuotientAltair uint64 `yaml:"INACTIVITY_PENALTY_QUOTIENT_ALTAIR" spec:"true"` // InactivityPenaltyQuotientAltair for penalties during inactivity post Altair hard fork.
|
||||
MinSlashingPenaltyQuotientAltair uint64 `yaml:"MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR" spec:"true"` // MinSlashingPenaltyQuotientAltair for slashing penalties post Altair hard fork.
|
||||
@@ -188,7 +189,7 @@ type BeaconChainConfig struct {
|
||||
// Bellatrix
|
||||
TerminalBlockHash common.Hash `yaml:"TERMINAL_BLOCK_HASH" spec:"true"` // TerminalBlockHash of beacon chain.
|
||||
TerminalBlockHashActivationEpoch types.Epoch `yaml:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH" spec:"true"` // TerminalBlockHashActivationEpoch of beacon chain.
|
||||
TerminalTotalDifficulty uint64 `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true"` // TerminalTotalDifficulty is part of the experimental Bellatrix spec. This value is type is currently TBD: https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#transition-settings
|
||||
TerminalTotalDifficulty *uint256.Int `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true"` // TerminalTotalDifficulty is part of the experimental Bellatrix spec. This value is type is currently TBD: https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#transition-settings
|
||||
FeeRecipient common.Address // FeeRecipient where the transaction fee goes to.
|
||||
}
|
||||
|
||||
|
||||
@@ -242,6 +242,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
|
||||
MinSlashingPenaltyQuotientBellatrix: 32,
|
||||
ProportionalSlashingMultiplierBellatrix: 3,
|
||||
InactivityPenaltyQuotientBellatrix: 1 << 24,
|
||||
TerminalBlockHash: [32]byte{},
|
||||
|
||||
// Light client
|
||||
MinSyncCommitteeParticipants: 1,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package params
|
||||
|
||||
const altairE2EForkEpoch = 6
|
||||
import "math"
|
||||
|
||||
const (
|
||||
altairE2EForkEpoch = 6
|
||||
MergeE2EForkEpoch = math.MaxUint64
|
||||
)
|
||||
|
||||
// UseE2EConfig for beacon chain services.
|
||||
func UseE2EConfig() {
|
||||
@@ -45,6 +50,9 @@ func E2ETestConfig() *BeaconChainConfig {
|
||||
// Altair Fork Parameters.
|
||||
e2eConfig.AltairForkEpoch = altairE2EForkEpoch
|
||||
|
||||
// Merge Fork Parameters.
|
||||
//e2eConfig.BellatrixForkVersion = MergeE2EForkEpoch // TODO_MERGE: Add a proper merge fork version when e2e is ready for it.
|
||||
|
||||
// Prysm constants.
|
||||
e2eConfig.ConfigName = ConfigNames[EndToEnd]
|
||||
|
||||
|
||||
53
config/params/testnet_kintsugi_config.go
Normal file
53
config/params/testnet_kintsugi_config.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// UseMergeTestNetworkConfig uses the Merge specific
|
||||
// network config.
|
||||
func UseMergeTestNetworkConfig() {
|
||||
cfg := BeaconNetworkConfig().Copy()
|
||||
cfg.ContractDeploymentBlock = 0
|
||||
cfg.BootstrapNodes = []string{
|
||||
"enr:-Iq4QKuNB_wHmWon7hv5HntHiSsyE1a6cUTK1aT7xDSU_hNTLW3R4mowUboCsqYoh1kN9v3ZoSu_WuvW9Aw0tQ0Dxv6GAXxQ7Nv5gmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk",
|
||||
"enr:-KG4QIkKUzDxrv7Xz8u9K9QqoTqEwKKCkLoChxVnfeILU6IdBoWoNOxPGvdl474l1iPFoR8CJUhgGEeO-k1SJ7SJCOEDhGV0aDKQR9ByjGEAAHAKAAAAAAAAAIJpZIJ2NIJpcISl6LnPiXNlY3AyNTZrMaEDprwHy6RKAKJguvGCldiGAI5JDJmQ8TZVnnWQur8zEh2DdGNwgiMog3VkcIIjKA",
|
||||
"enr:-Ly4QGJodG8Q0vX5ePXsLsXody1Fbeauyottk3-iAvJ_6XfTVlWGsnfBQPlIOBgexXJqD78bUD5OCnXF5igBBJ4WuboBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBH0HKMYQAAcAoAAAAAAAAAgmlkgnY0gmlwhEDhBN-Jc2VjcDI1NmsxoQPf98kXQf3Nh3ooc8vBdbUY2WAHR1VDrDhXYTKvRt4n-IhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
|
||||
"enr:-KG4QLIhAeEVABV4Id22qEbjemJ0b9JBjRhdYpKN0kvpVi_GbFkQTvAf7-Da-5sW2oNenTW3is_GxLImUCtYzxPMOR4DhGV0aDKQR9ByjGEAAHAKAAAAAAAAAIJpZIJ2NIJpcISl6LF5iXNlY3AyNTZrMaED6XFvht9SUPD0FlYWnjunXhF9FdQMQO56816C9iFNt-WDdGNwgiMog3VkcIIjKA",
|
||||
}
|
||||
OverrideBeaconNetworkConfig(cfg)
|
||||
}
|
||||
|
||||
// UseMergeTestConfig sets the main beacon chain
|
||||
// config for Merge testnet.
|
||||
func UseMergeTestConfig() {
|
||||
beaconConfig = KintsugiTestnetConfig()
|
||||
}
|
||||
|
||||
// KintsugiTestnetConfig defines the config for the Kingtsugi testnet.
|
||||
func KintsugiTestnetConfig() *BeaconChainConfig {
|
||||
cfg := MainnetConfig().Copy()
|
||||
cfg.MinGenesisActiveValidatorCount = 15000
|
||||
cfg.MinGenesisTime = 1639659600
|
||||
cfg.GenesisDelay = 300
|
||||
cfg.ConfigName = "Merge"
|
||||
cfg.GenesisForkVersion = []byte{0x60, 0x00, 0x00, 0x69}
|
||||
cfg.AltairForkVersion = []byte{0x61, 0x00, 0x00, 0x70}
|
||||
cfg.AltairForkEpoch = 10
|
||||
cfg.BellatrixForkVersion = []byte{0x62, 0x00, 0x00, 0x71}
|
||||
cfg.BellatrixForkEpoch = 20
|
||||
cfg.TerminalTotalDifficulty = uint256.NewInt(5000000000)
|
||||
cfg.TerminalBlockHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
cfg.TerminalBlockHashActivationEpoch = 18446744073709551615
|
||||
cfg.ShardingForkVersion = []byte{0x03, 0x00, 0x00, 0x00}
|
||||
cfg.ShardingForkEpoch = math.MaxUint64
|
||||
cfg.SecondsPerETH1Block = 14
|
||||
cfg.DepositChainID = 1337702
|
||||
cfg.DepositNetworkID = 1337702
|
||||
cfg.DepositContractAddress = "0x4242424242424242424242424242424242424242"
|
||||
cfg.Eth1FollowDistance = 16
|
||||
return cfg
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package params
|
||||
|
||||
import (
|
||||
eth1Params "github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// UsePraterNetworkConfig uses the Prater specific
|
||||
@@ -43,7 +44,7 @@ func PraterConfig() *BeaconChainConfig {
|
||||
cfg.AltairForkVersion = []byte{0x1, 0x0, 0x10, 0x20}
|
||||
cfg.ShardingForkVersion = []byte{0x3, 0x0, 0x10, 0x20}
|
||||
cfg.BellatrixForkVersion = []byte{0x2, 0x0, 0x10, 0x20}
|
||||
cfg.TransitionTotalDifficulty = 4294967296
|
||||
cfg.TerminalTotalDifficulty = uint256.NewInt(4294967296)
|
||||
cfg.DepositContractAddress = "0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b"
|
||||
return cfg
|
||||
}
|
||||
|
||||
7
deps.bzl
7
deps.bzl
@@ -825,8 +825,9 @@ def prysm_deps():
|
||||
importpath = "github.com/ethereum/go-ethereum",
|
||||
patch_args = ["-p1"],
|
||||
patches = ["//third_party:com_github_ethereum_go_ethereum_secp256k1.patch"],
|
||||
sum = "h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=",
|
||||
version = "v1.10.13",
|
||||
replace = "github.com/MariusVanDerWijden/go-ethereum",
|
||||
sum = "h1:5LBUQ4bwwam0O6ztBwXb7vSJWuitJ9poV780cqbLPAs=",
|
||||
version = "v1.8.22-0.20211208130742-dd90624af970",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
@@ -1185,6 +1186,7 @@ def prysm_deps():
|
||||
sum = "h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=",
|
||||
version = "v0.0.4",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_golangci_lint_1",
|
||||
importpath = "github.com/golangci/lint-1",
|
||||
@@ -2353,6 +2355,7 @@ def prysm_deps():
|
||||
sum = "h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4=",
|
||||
version = "v0.7.0",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_marten_seemann_qpack",
|
||||
importpath = "github.com/marten-seemann/qpack",
|
||||
|
||||
4
go.mod
4
go.mod
@@ -30,6 +30,7 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e
|
||||
github.com/holiman/uint256 v1.2.0
|
||||
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279
|
||||
github.com/ipfs/go-log/v2 v2.4.0
|
||||
github.com/joonix/log v0.0.0-20200409080653-9c1d2ceb5f1d
|
||||
@@ -104,7 +105,6 @@ require (
|
||||
github.com/go-logr/logr v0.2.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/go-playground/validator/v10 v10.10.0
|
||||
github.com/holiman/uint256 v1.2.0
|
||||
github.com/peterh/liner v1.2.0 // indirect
|
||||
github.com/prometheus/tsdb v0.10.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
|
||||
@@ -114,6 +114,8 @@ require (
|
||||
k8s.io/utils v0.0.0-20200520001619-278ece378a50 // indirect
|
||||
)
|
||||
|
||||
replace github.com/ethereum/go-ethereum => github.com/MariusVanDerWijden/go-ethereum v1.8.22-0.20211208130742-dd90624af970
|
||||
|
||||
replace github.com/json-iterator/go => github.com/prestonvanloon/go v1.1.7-0.20190722034630-4f2e55fcf87b
|
||||
|
||||
// See https://github.com/prysmaticlabs/grpc-gateway/issues/2
|
||||
|
||||
4
go.sum
4
go.sum
@@ -66,6 +66,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/MariusVanDerWijden/go-ethereum v1.8.22-0.20211208130742-dd90624af970 h1:5LBUQ4bwwam0O6ztBwXb7vSJWuitJ9poV780cqbLPAs=
|
||||
github.com/MariusVanDerWijden/go-ethereum v1.8.22-0.20211208130742-dd90624af970/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@@ -264,8 +266,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA=
|
||||
github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: dc04c886a976aeec2f44be5d57a2afbc88a4811ff4c318c6786b60e8749e5fd7
|
||||
// Hash: a9ca79248a2934a60aa64037e6c99f4407b0f1859d60dfc3a01389529682d36b
|
||||
package v1
|
||||
|
||||
import (
|
||||
|
||||
@@ -103,6 +103,7 @@ ssz_gen_marshal(
|
||||
"SigningData",
|
||||
"SyncCommittee",
|
||||
"SyncAggregatorSelectionData",
|
||||
"PowBlock",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
152
proto/prysm/v1alpha1/beacon_state.pb.go
generated
152
proto/prysm/v1alpha1/beacon_state.pb.go
generated
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.15.8
|
||||
// source: proto/prysm/v1alpha1/beacon_state.proto
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
github_com_prysmaticlabs_eth2_types "github.com/prysmaticlabs/eth2-types"
|
||||
github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield"
|
||||
_ "github.com/prysmaticlabs/prysm/proto/eth/ext"
|
||||
@@ -25,10 +24,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type BeaconState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1463,6 +1458,69 @@ func (x *ExecutionPayloadHeader) GetTransactionsRoot() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PowBlock struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
BlockHash []byte `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty" ssz-size:"32"`
|
||||
ParentHash []byte `protobuf:"bytes,2,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty" ssz-size:"32"`
|
||||
TotalDifficulty []byte `protobuf:"bytes,3,opt,name=total_difficulty,json=totalDifficulty,proto3" json:"total_difficulty,omitempty" ssz-size:"32"`
|
||||
}
|
||||
|
||||
func (x *PowBlock) Reset() {
|
||||
*x = PowBlock{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PowBlock) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PowBlock) ProtoMessage() {}
|
||||
|
||||
func (x *PowBlock) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[14]
|
||||
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 PowBlock.ProtoReflect.Descriptor instead.
|
||||
func (*PowBlock) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_beacon_state_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *PowBlock) GetBlockHash() []byte {
|
||||
if x != nil {
|
||||
return x.BlockHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PowBlock) GetParentHash() []byte {
|
||||
if x != nil {
|
||||
return x.ParentHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PowBlock) GetTotalDifficulty() []byte {
|
||||
if x != nil {
|
||||
return x.TotalDifficulty
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_proto_prysm_v1alpha1_beacon_state_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{
|
||||
@@ -1931,7 +1989,16 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{
|
||||
0x68, 0x12, 0x33, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
|
||||
0x18, 0x02, 0x33, 0x32, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65,
|
||||
0x6e, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x08, 0x50, 0x6f, 0x77, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73,
|
||||
0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
|
||||
0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42,
|
||||
0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48,
|
||||
0x61, 0x73, 0x68, 0x12, 0x31, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x66,
|
||||
0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a,
|
||||
0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66,
|
||||
0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 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, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
@@ -1956,7 +2023,7 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_rawDescGZIP() []byte {
|
||||
return file_proto_prysm_v1alpha1_beacon_state_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
|
||||
var file_proto_prysm_v1alpha1_beacon_state_proto_goTypes = []interface{}{
|
||||
(*BeaconState)(nil), // 0: ethereum.eth.v1alpha1.BeaconState
|
||||
(*BeaconStateAltair)(nil), // 1: ethereum.eth.v1alpha1.BeaconStateAltair
|
||||
@@ -1972,43 +2039,44 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_goTypes = []interface{}{
|
||||
(*SyncAggregatorSelectionData)(nil), // 11: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
(*BeaconStateBellatrix)(nil), // 12: ethereum.eth.v1alpha1.BeaconStateBellatrix
|
||||
(*ExecutionPayloadHeader)(nil), // 13: ethereum.eth.v1alpha1.ExecutionPayloadHeader
|
||||
(*BeaconBlockHeader)(nil), // 14: ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
(*Eth1Data)(nil), // 15: ethereum.eth.v1alpha1.Eth1Data
|
||||
(*Validator)(nil), // 16: ethereum.eth.v1alpha1.Validator
|
||||
(*Checkpoint)(nil), // 17: ethereum.eth.v1alpha1.Checkpoint
|
||||
(*AttestationData)(nil), // 18: ethereum.eth.v1alpha1.AttestationData
|
||||
(*PowBlock)(nil), // 14: ethereum.eth.v1alpha1.PowBlock
|
||||
(*BeaconBlockHeader)(nil), // 15: ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
(*Eth1Data)(nil), // 16: ethereum.eth.v1alpha1.Eth1Data
|
||||
(*Validator)(nil), // 17: ethereum.eth.v1alpha1.Validator
|
||||
(*Checkpoint)(nil), // 18: ethereum.eth.v1alpha1.Checkpoint
|
||||
(*AttestationData)(nil), // 19: ethereum.eth.v1alpha1.AttestationData
|
||||
}
|
||||
var file_proto_prysm_v1alpha1_beacon_state_proto_depIdxs = []int32{
|
||||
2, // 0: ethereum.eth.v1alpha1.BeaconState.fork:type_name -> ethereum.eth.v1alpha1.Fork
|
||||
14, // 1: ethereum.eth.v1alpha1.BeaconState.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
15, // 2: ethereum.eth.v1alpha1.BeaconState.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
15, // 3: ethereum.eth.v1alpha1.BeaconState.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 4: ethereum.eth.v1alpha1.BeaconState.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
15, // 1: ethereum.eth.v1alpha1.BeaconState.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
16, // 2: ethereum.eth.v1alpha1.BeaconState.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 3: ethereum.eth.v1alpha1.BeaconState.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
17, // 4: ethereum.eth.v1alpha1.BeaconState.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
3, // 5: ethereum.eth.v1alpha1.BeaconState.previous_epoch_attestations:type_name -> ethereum.eth.v1alpha1.PendingAttestation
|
||||
3, // 6: ethereum.eth.v1alpha1.BeaconState.current_epoch_attestations:type_name -> ethereum.eth.v1alpha1.PendingAttestation
|
||||
17, // 7: ethereum.eth.v1alpha1.BeaconState.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 8: ethereum.eth.v1alpha1.BeaconState.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 9: ethereum.eth.v1alpha1.BeaconState.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 7: ethereum.eth.v1alpha1.BeaconState.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 8: ethereum.eth.v1alpha1.BeaconState.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 9: ethereum.eth.v1alpha1.BeaconState.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
2, // 10: ethereum.eth.v1alpha1.BeaconStateAltair.fork:type_name -> ethereum.eth.v1alpha1.Fork
|
||||
14, // 11: ethereum.eth.v1alpha1.BeaconStateAltair.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
15, // 12: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
15, // 13: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 14: ethereum.eth.v1alpha1.BeaconStateAltair.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
17, // 15: ethereum.eth.v1alpha1.BeaconStateAltair.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 16: ethereum.eth.v1alpha1.BeaconStateAltair.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 17: ethereum.eth.v1alpha1.BeaconStateAltair.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
15, // 11: ethereum.eth.v1alpha1.BeaconStateAltair.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
16, // 12: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 13: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
17, // 14: ethereum.eth.v1alpha1.BeaconStateAltair.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
18, // 15: ethereum.eth.v1alpha1.BeaconStateAltair.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 16: ethereum.eth.v1alpha1.BeaconStateAltair.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 17: ethereum.eth.v1alpha1.BeaconStateAltair.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
10, // 18: ethereum.eth.v1alpha1.BeaconStateAltair.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
|
||||
10, // 19: ethereum.eth.v1alpha1.BeaconStateAltair.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
|
||||
18, // 20: ethereum.eth.v1alpha1.PendingAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
19, // 20: ethereum.eth.v1alpha1.PendingAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
2, // 21: ethereum.eth.v1alpha1.CheckPtInfo.fork:type_name -> ethereum.eth.v1alpha1.Fork
|
||||
2, // 22: ethereum.eth.v1alpha1.BeaconStateBellatrix.fork:type_name -> ethereum.eth.v1alpha1.Fork
|
||||
14, // 23: ethereum.eth.v1alpha1.BeaconStateBellatrix.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
15, // 24: ethereum.eth.v1alpha1.BeaconStateBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
15, // 25: ethereum.eth.v1alpha1.BeaconStateBellatrix.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 26: ethereum.eth.v1alpha1.BeaconStateBellatrix.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
17, // 27: ethereum.eth.v1alpha1.BeaconStateBellatrix.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 28: ethereum.eth.v1alpha1.BeaconStateBellatrix.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
17, // 29: ethereum.eth.v1alpha1.BeaconStateBellatrix.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
15, // 23: ethereum.eth.v1alpha1.BeaconStateBellatrix.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
|
||||
16, // 24: ethereum.eth.v1alpha1.BeaconStateBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
16, // 25: ethereum.eth.v1alpha1.BeaconStateBellatrix.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
|
||||
17, // 26: ethereum.eth.v1alpha1.BeaconStateBellatrix.validators:type_name -> ethereum.eth.v1alpha1.Validator
|
||||
18, // 27: ethereum.eth.v1alpha1.BeaconStateBellatrix.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 28: ethereum.eth.v1alpha1.BeaconStateBellatrix.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
18, // 29: ethereum.eth.v1alpha1.BeaconStateBellatrix.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
|
||||
10, // 30: ethereum.eth.v1alpha1.BeaconStateBellatrix.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
|
||||
10, // 31: ethereum.eth.v1alpha1.BeaconStateBellatrix.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
|
||||
13, // 32: ethereum.eth.v1alpha1.BeaconStateBellatrix.latest_execution_payload_header:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadHeader
|
||||
@@ -2196,6 +2264,18 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PowBlock); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -2203,7 +2283,7 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 14,
|
||||
NumMessages: 15,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -251,3 +251,9 @@ message ExecutionPayloadHeader {
|
||||
bytes block_hash = 13 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
bytes transactions_root = 14 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
}
|
||||
|
||||
message PowBlock {
|
||||
bytes block_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
bytes parent_hash = 2 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
bytes total_difficulty = 3 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
}
|
||||
|
||||
14
testing/spectest/mainnet/bellatrix/forkchoice/BUILD.bazel
Normal file
14
testing/spectest/mainnet/bellatrix/forkchoice/BUILD.bazel
Normal file
@@ -0,0 +1,14 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_test")
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["forkchoice_test.go"],
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@consensus_spec_tests_mainnet//:test_data",
|
||||
],
|
||||
tags = ["spectest"],
|
||||
deps = [
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/spectest/shared/common/forkchoice:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
package forkchoice
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/testing/spectest/shared/common/forkchoice"
|
||||
)
|
||||
|
||||
func TestMainnet_Bellatrix_Forkchoice(t *testing.T) {
|
||||
forkchoice.Run(t, "mainnet", version.Bellatrix)
|
||||
}
|
||||
18
testing/spectest/minimal/bellatrix/forkchoice/BUILD.bazel
Normal file
18
testing/spectest/minimal/bellatrix/forkchoice/BUILD.bazel
Normal file
@@ -0,0 +1,18 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_test")
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["forkchoice_test.go"],
|
||||
data = glob(["*.yaml"]) + [
|
||||
"@consensus_spec_tests_minimal//:test_data",
|
||||
],
|
||||
eth_network = "minimal",
|
||||
tags = [
|
||||
"minimal",
|
||||
"spectest",
|
||||
],
|
||||
deps = [
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/spectest/shared/common/forkchoice:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
package forkchoice
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/testing/spectest/shared/common/forkchoice"
|
||||
)
|
||||
|
||||
func TestMinimal_Bellatrix_Forkchoice(t *testing.T) {
|
||||
forkchoice.Run(t, "minimal", version.Bellatrix)
|
||||
}
|
||||
@@ -4,6 +4,7 @@ go_library(
|
||||
name = "go_default_library",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"execution_engine_mock.go",
|
||||
"runner.go",
|
||||
"service.go",
|
||||
"type.go",
|
||||
@@ -18,6 +19,7 @@ go_library(
|
||||
"//beacon-chain/db/testing:go_default_library",
|
||||
"//beacon-chain/forkchoice/protoarray:go_default_library",
|
||||
"//beacon-chain/operations/attestations:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/state/v1:go_default_library",
|
||||
@@ -34,7 +36,10 @@ go_library(
|
||||
"//testing/spectest/utils:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//eth/catalyst:go_default_library",
|
||||
"@com_github_golang_snappy//:go_default_library",
|
||||
"@com_github_holiman_uint256//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
55
testing/spectest/shared/common/forkchoice/execution_engine_mock.go
generated
Normal file
55
testing/spectest/shared/common/forkchoice/execution_engine_mock.go
generated
Normal file
@@ -0,0 +1,55 @@
|
||||
package forkchoice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type ExecutionEngineMock struct {
|
||||
powBlocks map[[32]byte]*eth.PowBlock
|
||||
}
|
||||
|
||||
func (m *ExecutionEngineMock) PreparePayload(context.Context, catalyst.ForkchoiceStateV1, catalyst.PayloadAttributesV1) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (m *ExecutionEngineMock) GetPayload(context.Context, string) (*catalyst.ExecutableDataV1, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *ExecutionEngineMock) NotifyForkChoiceValidated(context.Context, catalyst.ForkchoiceStateV1) error {
|
||||
return nil
|
||||
}
|
||||
func (m *ExecutionEngineMock) ExecutePayload(context.Context, *catalyst.ExecutableDataV1) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *ExecutionEngineMock) LatestExecutionBlock() (*powchain.ExecutionBlock, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *ExecutionEngineMock) ExecutionBlockByHash(blockHash common.Hash) (*powchain.ExecutionBlock, error) {
|
||||
b, ok := m.powBlocks[bytesutil.ToBytes32(blockHash.Bytes())]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
tdInBigEndian := bytesutil.ReverseByteOrder(b.TotalDifficulty)
|
||||
tdBigint := new(big.Int)
|
||||
tdBigint.SetBytes(tdInBigEndian)
|
||||
td256, of := uint256.FromBig(tdBigint)
|
||||
if of {
|
||||
return nil, errors.New("could not convert big.Int to uint256")
|
||||
}
|
||||
|
||||
return &powchain.ExecutionBlock{
|
||||
ParentHash: common.Bytes2Hex(b.ParentHash),
|
||||
TotalDifficulty: td256.String(),
|
||||
Hash: common.Bytes2Hex(b.BlockHash),
|
||||
}, nil
|
||||
}
|
||||
@@ -3,12 +3,14 @@ package forkchoice
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/golang/snappy"
|
||||
"github.com/holiman/uint256"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||
@@ -53,6 +55,15 @@ func Run(t *testing.T, config string, fork int) {
|
||||
blockSSZ, err := snappy.Decode(nil /* dst */, blockFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := params.BeaconConfig()
|
||||
b, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007913129638912", 10)
|
||||
ttd, of := uint256.FromBig(b)
|
||||
if of {
|
||||
t.Fatal("Could not set big int")
|
||||
}
|
||||
cfg.TerminalTotalDifficulty = ttd
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
|
||||
var beaconState state.BeaconState
|
||||
var beaconBlock block.SignedBeaconBlock
|
||||
switch fork {
|
||||
@@ -69,7 +80,10 @@ func Run(t *testing.T, config string, fork int) {
|
||||
t.Fatalf("unknown fork version: %v", fork)
|
||||
}
|
||||
|
||||
service := startChainService(t, beaconState, beaconBlock)
|
||||
execMock := &ExecutionEngineMock{
|
||||
powBlocks: make(map[[32]byte]*ethpb.PowBlock),
|
||||
}
|
||||
service := startChainService(t, beaconState, beaconBlock, execMock)
|
||||
var lastTick int64
|
||||
for _, step := range steps {
|
||||
if step.Tick != nil {
|
||||
@@ -114,6 +128,18 @@ func Run(t *testing.T, config string, fork int) {
|
||||
require.NoError(t, att.UnmarshalSSZ(attSSZ), "Failed to unmarshal")
|
||||
require.NoError(t, service.OnAttestation(ctx, att))
|
||||
}
|
||||
if step.PowBlock != nil {
|
||||
powBlockFile, err := util.BazelFileBytes(testsFolderPath, folder.Name(), fmt.Sprint(*step.PowBlock, ".ssz_snappy"))
|
||||
require.NoError(t, err)
|
||||
p, err := snappy.Decode(nil /* dst */, powBlockFile)
|
||||
require.NoError(t, err)
|
||||
pb := ðpb.PowBlock{}
|
||||
require.NoError(t, pb.UnmarshalSSZ(p), "Failed to unmarshal")
|
||||
execMock.powBlocks[bytesutil.ToBytes32(pb.BlockHash)] = pb
|
||||
tdInBigEndian := bytesutil.ReverseByteOrder(pb.TotalDifficulty)
|
||||
tdBigint := new(big.Int)
|
||||
tdBigint.SetBytes(tdInBigEndian)
|
||||
}
|
||||
if step.Check != nil {
|
||||
require.NoError(t, service.UpdateHeadWithBalances(ctx))
|
||||
c := step.Check
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
func startChainService(t *testing.T, st state.BeaconState, block block.SignedBeaconBlock) *blockchain.Service {
|
||||
func startChainService(t *testing.T, st state.BeaconState, block block.SignedBeaconBlock, engineMock *ExecutionEngineMock) *blockchain.Service {
|
||||
db := testDB.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
require.NoError(t, db.SaveBlock(ctx, block))
|
||||
@@ -42,6 +42,7 @@ func startChainService(t *testing.T, st state.BeaconState, block block.SignedBea
|
||||
require.NoError(t, err)
|
||||
|
||||
opts := append([]blockchain.Option{},
|
||||
blockchain.WithExecutionEngineCaller(engineMock),
|
||||
blockchain.WithFinalizedStateAtStartUp(st),
|
||||
blockchain.WithDatabase(db),
|
||||
blockchain.WithAttestationService(attPool),
|
||||
|
||||
@@ -5,6 +5,7 @@ type Step struct {
|
||||
Block *string `json:"block"`
|
||||
Valid *bool `json:"valid"`
|
||||
Attestation *string `json:"attestation"`
|
||||
PowBlock *string `json:"pow_block"`
|
||||
Check *Check `json:"checks"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user