Better caplin logging and logic (#7992)

This commit is contained in:
Giulio rebuffo 2023-08-10 22:34:58 +02:00 committed by GitHub
parent 6dfe491d30
commit e3a59ed902
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 118 additions and 806 deletions

View File

@ -105,7 +105,6 @@ erigon: go-version erigon.cmd
@rm -f $(GOBIN)/tg # Remove old binary to prevent confusion where users still use it because of the scripts
COMMANDS += devnet
COMMANDS += erigon-el-mock
COMMANDS += downloader
COMMANDS += hack
COMMANDS += integration

View File

@ -68,6 +68,11 @@ var (
"enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM",
"enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM",
}
SepoliaBootstrapNodes = append(MainnetBootstrapNodes,
"enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk",
"enr:-Ly4QFoZTWR8ulxGVsWydTNGdwEESueIdj-wB6UmmjUcm-AOPxnQi7wprzwcdo7-1jBW_JxELlUKJdJES8TDsbl1EdNlh2F0dG5ldHOI__78_v2bsV-EZXRoMpA2-lATkAAAcf__________gmlkgnY0gmlwhBLYJjGJc2VjcDI1NmsxoQI0gujXac9rMAb48NtMqtSTyHIeNYlpjkbYpWJw46PmYYhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA",
"enr:-KG4QE5OIg5ThTjkzrlVF32WT_-XT14WeJtIz2zoTqLLjQhYAmJlnk4ItSoH41_2x0RX0wTFIe5GgjRzU2u7Q1fN4vADhGV0aDKQqP7o7pAAAHAyAAAAAAAAAIJpZIJ2NIJpcISlFsStiXNlY3AyNTZrMaEC-Rrd_bBZwhKpXzFCrStKp1q_HmGOewxY3KwM8ofAj_ODdGNwgiMog3VkcIIjKA",
"enr:-L64QC9Hhov4DhQ7mRukTOz4_jHm4DHlGL726NWH4ojH1wFgEwSin_6H95Gs6nW2fktTWbPachHJ6rUFu0iJNgA0SB2CARqHYXR0bmV0c4j__________4RldGgykDb6UBOQAABx__________-CaWSCdjSCaXCEA-2vzolzZWNwMjU2azGhA17lsUg60R776rauYMdrAz383UUgESoaHEzMkvm4K6k6iHN5bmNuZXRzD4N0Y3CCIyiDdWRwgiMo")
GnosisBootstrapNodes = append(MainnetBootstrapNodes, []string{
"enr:-Ly4QMU1y81COwm1VZgxGF4_eZ21ub9-GHF6dXZ29aEJ0oZpcV2Rysw-viaEKfpcpu9ZarILJLxFZjcKOjE0Sybs3MQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANLnx-Jc2VjcDI1NmsxoQKoaYT8I-wf2I_f_ii6EgoSSXj5T3bhiDyW-7ZLsY3T64hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA",
@ -159,7 +164,7 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig
SyncCommsSubnetKey: "syncnets",
MinimumPeersInSubnetSearch: 20,
ContractDeploymentBlock: 1273020,
BootNodes: MainnetBootstrapNodes,
BootNodes: SepoliaBootstrapNodes,
},
GoerliNetwork: {
@ -809,14 +814,17 @@ func gnosisConfig() BeaconChainConfig {
cfg.AltairForkVersion = 0x01000064
cfg.BellatrixForkEpoch = 385536
cfg.BellatrixForkVersion = 0x02000064
cfg.CapellaForkEpoch = 648704
cfg.CapellaForkVersion = 0x03000064
cfg.TerminalTotalDifficulty = "8626000000000000000000058750000000000000000000"
cfg.DepositContractAddress = "0x0B98057eA310F4d31F2a452B414647007d1645d9"
cfg.BaseRewardFactor = 25
cfg.SlotsPerEpoch = 16
cfg.EpochsPerSyncCommitteePeriod = 512
cfg.CapellaForkEpoch = 648704
cfg.CapellaForkVersion = 0x03000064
cfg.DenebForkEpoch = math.MaxUint64
cfg.InactivityScoreRecoveryRate = 16
cfg.InactivityScoreBias = 4
cfg.MaxWithdrawalsPerPayload = 8
cfg.InitializeForkSchedule()
return cfg
}

View File

@ -44,7 +44,7 @@ func (s *StageGraph[CONFIG, ARGUMENTS]) StartWithStage(ctx context.Context, star
err := <-errch
dur := time.Since(start)
if err != nil {
lg.Error("error executing clstage", "err", err)
lg.Debug("error executing clstage", "err", err)
}
select {
case <-ctx.Done():
@ -52,7 +52,7 @@ func (s *StageGraph[CONFIG, ARGUMENTS]) StartWithStage(ctx context.Context, star
default:
args = s.ArgsFunc(ctx, cfg)
nextStage := currentStage.TransitionFunc(cfg, args, err)
logger.Info("clstage finish", "stage", stageName, "in", dur, "next", nextStage)
logger.Debug("clstage finish", "stage", stageName, "in", dur, "next", nextStage)
stageName = nextStage
}
}

View File

@ -62,11 +62,24 @@ type BeaconBody struct {
// With a max of 4 per block
BlobKzgCommitments *solid.ListSSZ[*KZGCommitment]
// The version of the beacon chain
Version clparams.StateVersion
Version clparams.StateVersion
beaconCfg *clparams.BeaconChainConfig
}
// Getters
func NewSignedBeaconBlock(beaconCfg *clparams.BeaconChainConfig) *SignedBeaconBlock {
return &SignedBeaconBlock{Block: NewBeaconBlock(beaconCfg)}
}
func NewBeaconBlock(beaconCfg *clparams.BeaconChainConfig) *BeaconBlock {
return &BeaconBlock{Body: NewBeaconBody(beaconCfg)}
}
func NewBeaconBody(beaconCfg *clparams.BeaconChainConfig) *BeaconBody {
return &BeaconBody{beaconCfg: beaconCfg}
}
// Version returns beacon block version.
func (b *SignedBeaconBlock) Version() clparams.StateVersion {
return b.Block.Body.Version
@ -90,7 +103,7 @@ func (b *BeaconBody) EncodingSizeSSZ() (size int) {
b.SyncAggregate = &SyncAggregate{}
}
if b.ExecutionPayload == nil {
b.ExecutionPayload = &Eth1Block{}
b.ExecutionPayload = NewEth1Block(b.Version, b.beaconCfg)
}
if b.ProposerSlashings == nil {
b.ProposerSlashings = solid.NewStaticListSSZ[*ProposerSlashing](MaxProposerSlashings, 416)
@ -108,7 +121,7 @@ func (b *BeaconBody) EncodingSizeSSZ() (size int) {
b.VoluntaryExits = solid.NewStaticListSSZ[*SignedVoluntaryExit](MaxVoluntaryExits, 112)
}
if b.ExecutionPayload == nil {
b.ExecutionPayload = new(Eth1Block)
b.ExecutionPayload = NewEth1Block(b.Version, b.beaconCfg)
}
if b.ExecutionChanges == nil {
b.ExecutionChanges = solid.NewStaticListSSZ[*SignedBLSToExecutionChange](MaxExecutionChanges, 172)
@ -173,13 +186,12 @@ func (b *BeaconBlock) EncodeSSZ(buf []byte) (dst []byte, err error) {
func (b *BeaconBlock) EncodingSizeSSZ() int {
if b.Body == nil {
b.Body = new(BeaconBody)
return 80
}
return 80 + b.Body.EncodingSizeSSZ()
}
func (b *BeaconBlock) DecodeSSZ(buf []byte, version int) error {
b.Body = new(BeaconBody)
return ssz2.UnmarshalSSZ(buf, version, &b.Slot, &b.ProposerIndex, b.ParentRoot[:], b.StateRoot[:], b.Body)
}
@ -193,13 +205,12 @@ func (b *SignedBeaconBlock) EncodeSSZ(buf []byte) ([]byte, error) {
func (b *SignedBeaconBlock) EncodingSizeSSZ() int {
if b.Block == nil {
b.Block = new(BeaconBlock)
return 100
}
return 100 + b.Block.EncodingSizeSSZ()
}
func (b *SignedBeaconBlock) DecodeSSZ(buf []byte, s int) error {
b.Block = new(BeaconBlock)
return ssz2.UnmarshalSSZ(buf, s, b.Block, b.Signature[:])
}

View File

@ -43,10 +43,11 @@ func TestBeaconBody(t *testing.T) {
Deposits: deposits,
VoluntaryExits: voluntaryExits,
SyncAggregate: syncAggregate,
ExecutionPayload: NewEth1BlockFromHeaderAndBody(block.Header(), block.RawBody()),
ExecutionPayload: NewEth1BlockFromHeaderAndBody(block.Header(), block.RawBody(), &clparams.MainnetBeaconConfig),
ExecutionChanges: executionChanges,
BlobKzgCommitments: blobKzgCommitments,
Version: version,
beaconCfg: &clparams.MainnetBeaconConfig,
}
// Test EncodeSSZ and DecodeSSZ

View File

@ -4,20 +4,20 @@ import (
"github.com/ledgerwatch/erigon-lib/types/clonable"
)
func (*SignedBeaconBlock) Clone() clonable.Clonable {
return &SignedBeaconBlock{}
func (s *SignedBeaconBlock) Clone() clonable.Clonable {
return NewSignedBeaconBlock(s.Block.Body.beaconCfg)
}
func (*IndexedAttestation) Clone() clonable.Clonable {
return &IndexedAttestation{}
}
func (*BeaconBody) Clone() clonable.Clonable {
return &BeaconBody{}
func (b *BeaconBody) Clone() clonable.Clonable {
return NewBeaconBody(b.beaconCfg)
}
func (*Eth1Block) Clone() clonable.Clonable {
return &Eth1Block{}
func (e *Eth1Block) Clone() clonable.Clonable {
return NewEth1Block(e.version, e.beaconCfg)
}
func (*Eth1Data) Clone() clonable.Clonable {
@ -72,8 +72,8 @@ func (*Deposit) Clone() clonable.Clonable {
return &Deposit{}
}
func (*BeaconBlock) Clone() clonable.Clonable {
return &BeaconBlock{}
func (b *BeaconBlock) Clone() clonable.Clonable {
return NewBeaconBlock(b.Body.beaconCfg)
}
func (*AggregateAndProof) Clone() clonable.Clonable {

View File

@ -35,16 +35,17 @@ type Eth1Block struct {
BlobGasUsed uint64
ExcessBlobGas uint64
// internals
version clparams.StateVersion
version clparams.StateVersion
beaconCfg *clparams.BeaconChainConfig
}
// NewEth1Block creates a new Eth1Block.
func NewEth1Block(version clparams.StateVersion) *Eth1Block {
return &Eth1Block{version: version}
func NewEth1Block(version clparams.StateVersion, beaconCfg *clparams.BeaconChainConfig) *Eth1Block {
return &Eth1Block{version: version, beaconCfg: beaconCfg}
}
// NewEth1BlockFromHeaderAndBody with given header/body.
func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody) *Eth1Block {
func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody, beaconCfg *clparams.BeaconChainConfig) *Eth1Block {
baseFeeBytes := header.BaseFee.Bytes()
for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 {
baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i]
@ -69,7 +70,8 @@ func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody) *E
BaseFeePerGas: baseFee32,
BlockHash: header.Hash(),
Transactions: solid.NewTransactionsSSZFromTransactions(body.Transactions),
Withdrawals: solid.NewStaticListSSZFromList(body.Withdrawals, 16, 44),
Withdrawals: solid.NewStaticListSSZFromList(body.Withdrawals, int(beaconCfg.MaxWithdrawalsPerPayload), 44),
beaconCfg: beaconCfg,
}
if header.BlobGasUsed != nil && header.ExcessBlobGas != nil {
@ -143,7 +145,7 @@ func (b *Eth1Block) EncodingSizeSSZ() (size int) {
if b.version >= clparams.CapellaVersion {
if b.Withdrawals == nil {
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](16, 44)
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
}
size += b.Withdrawals.EncodingSizeSSZ() + 4
}
@ -159,7 +161,7 @@ func (b *Eth1Block) EncodingSizeSSZ() (size int) {
func (b *Eth1Block) DecodeSSZ(buf []byte, version int) error {
b.Extra = solid.NewExtraData()
b.Transactions = &solid.TransactionsSSZ{}
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](16, 44)
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
b.version = clparams.StateVersion(version)
return ssz2.UnmarshalSSZ(buf, version, b.getSchema()...)
}

View File

@ -75,7 +75,7 @@ func (c *Case) Domino(ctx context.Context, slot uint64) (*cltypes.SignedBeaconBl
return nil, err
}
_, version := c.EpochAndVersion()
blk := &cltypes.SignedBeaconBlock{}
blk := cltypes.NewSignedBeaconBlock(c.BeaconConfig)
err = blk.DecodeSSZ(bts, version)
if err != nil {
return nil, err

View File

@ -69,7 +69,7 @@ func ReadBeaconBlock(tx kv.RwTx, blockRoot libcommon.Hash, slot uint64, version
if encodedBeaconBlock, err = utils.DecompressSnappy(encodedBeaconBlock); err != nil {
return nil, 0, libcommon.Hash{}, err
}
signedBlock := new(cltypes.SignedBeaconBlock)
signedBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
if err := signedBlock.DecodeSSZ(encodedBeaconBlock, int(version)); err != nil {
return nil, 0, libcommon.Hash{}, err
}

View File

@ -14,7 +14,7 @@ import (
func TestBeaconBlock(t *testing.T) {
_, tx := memdb.NewTestTx(t)
signedBeaconBlock := new(cltypes.SignedBeaconBlock)
signedBeaconBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
require.NoError(t, signedBeaconBlock.DecodeSSZ(rawdb.SSZTestBeaconBlock, int(clparams.BellatrixVersion)))
root, err := signedBeaconBlock.Block.HashSSZ()
@ -33,7 +33,7 @@ func TestBeaconBlock(t *testing.T) {
func TestFinalizedBlockRoot(t *testing.T) {
_, tx := memdb.NewTestTx(t)
signedBeaconBlock := new(cltypes.SignedBeaconBlock)
signedBeaconBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
require.NoError(t, signedBeaconBlock.DecodeSSZ(rawdb.SSZTestBeaconBlock, int(clparams.BellatrixVersion)))
root, err := signedBeaconBlock.Block.HashSSZ()

View File

@ -1,251 +0,0 @@
package execution_client
import (
"context"
"encoding/binary"
"fmt"
"math/big"
"time"
"github.com/c2h5oh/datasize"
"github.com/holiman/uint256"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/log/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/keepalive"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/cl/phase1/execution_client/rpc_helper"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/turbo/engineapi/engine_types"
)
const fcuTimeout = 12 * time.Second
// ExecutionClient interfaces with the Erigon-EL component consensus side.
type ExecutionClient struct {
client execution.ExecutionClient
ctx context.Context
}
func HeaderRpcToHeader(header *execution.Header) (*types.Header, error) {
var blockNonce types.BlockNonce
binary.BigEndian.PutUint64(blockNonce[:], header.Nonce)
h := &types.Header{
ParentHash: gointerfaces.ConvertH256ToHash(header.ParentHash),
UncleHash: gointerfaces.ConvertH256ToHash(header.OmmerHash),
Coinbase: gointerfaces.ConvertH160toAddress(header.Coinbase),
Root: gointerfaces.ConvertH256ToHash(header.StateRoot),
TxHash: gointerfaces.ConvertH256ToHash(header.TransactionHash),
ReceiptHash: gointerfaces.ConvertH256ToHash(header.ReceiptRoot),
Bloom: gointerfaces.ConvertH2048ToBloom(header.LogsBloom),
Difficulty: gointerfaces.ConvertH256ToUint256Int(header.Difficulty).ToBig(),
Number: big.NewInt(int64(header.BlockNumber)),
GasLimit: header.GasLimit,
GasUsed: header.GasUsed,
Time: header.Timestamp,
Extra: header.ExtraData,
MixDigest: gointerfaces.ConvertH256ToHash(header.PrevRandao),
Nonce: blockNonce,
}
if header.BaseFeePerGas != nil {
h.BaseFee = gointerfaces.ConvertH256ToUint256Int(header.BaseFeePerGas).ToBig()
}
if header.WithdrawalHash != nil {
h.WithdrawalsHash = new(libcommon.Hash)
*h.WithdrawalsHash = gointerfaces.ConvertH256ToHash(header.WithdrawalHash)
}
blockHash := gointerfaces.ConvertH256ToHash(header.BlockHash)
if blockHash != h.Hash() {
return nil, fmt.Errorf("block %d, %x has invalid hash. expected: %x", header.BlockNumber, h.Hash(), blockHash)
}
return h, nil
}
func HeaderToHeaderRPC(header *types.Header) *execution.Header {
difficulty := new(uint256.Int)
difficulty.SetFromBig(header.Difficulty)
var baseFeeReply *types2.H256
if header.BaseFee != nil {
var baseFee uint256.Int
baseFee.SetFromBig(header.BaseFee)
baseFeeReply = gointerfaces.ConvertUint256IntToH256(&baseFee)
}
var withdrawalHashReply *types2.H256
if header.WithdrawalsHash != nil {
withdrawalHashReply = gointerfaces.ConvertHashToH256(*header.WithdrawalsHash)
}
return &execution.Header{
ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash),
Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase),
StateRoot: gointerfaces.ConvertHashToH256(header.Root),
TransactionHash: gointerfaces.ConvertHashToH256(header.TxHash),
LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]),
ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash),
PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest),
BlockNumber: header.Number.Uint64(),
Nonce: header.Nonce.Uint64(),
GasLimit: header.GasLimit,
GasUsed: header.GasUsed,
Timestamp: header.Time,
ExtraData: header.Extra,
Difficulty: gointerfaces.ConvertUint256IntToH256(difficulty),
BlockHash: gointerfaces.ConvertHashToH256(header.Hash()),
OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash),
BaseFeePerGas: baseFeeReply,
WithdrawalHash: withdrawalHashReply,
}
}
// NewExecutionClient establishes a client-side connection with Erigon-EL
func NewExecutionClient(ctx context.Context, addr string) (*ExecutionClient, error) {
// Set up dial options for the gRPC client connection
var dialOpts []grpc.DialOption
dialOpts = []grpc.DialOption{
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(int(16 * datasize.MB))),
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 5 * time.Minute,
Timeout: 10 * time.Minute,
PermitWithoutStream: true,
}),
}
// Add transport credentials to the dial options
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
// Create the gRPC client connection
conn, err := grpc.DialContext(ctx, addr, dialOpts...)
if err != nil {
// Return an error if the connection fails
return nil, fmt.Errorf("creating client connection to execution client: %w", err)
}
// Return a new ExecutionClient struct with the gRPC client and context set as fields
return &ExecutionClient{
client: execution.NewExecutionClient(conn),
ctx: ctx,
}, nil
}
// InsertHeaders will send block bodies to execution client
func (ec *ExecutionClient) InsertHeaders(headers []*types.Header) error {
grpcHeaders := make([]*execution.Header, 0, len(headers))
for _, header := range headers {
grpcHeaders = append(grpcHeaders, HeaderToHeaderRPC(header))
}
_, err := ec.client.InsertHeaders(ec.ctx, &execution.InsertHeadersRequest{Headers: grpcHeaders})
return err
}
// InsertBodies will send block bodies to execution client
func (ec *ExecutionClient) InsertBodies(bodies []*types.RawBody, blockHashes []libcommon.Hash, blockNumbers []uint64) error {
if len(bodies) != len(blockHashes) || len(bodies) != len(blockNumbers) {
return fmt.Errorf("unbalanced inputs")
}
grpcBodies := make([]*execution.BlockBody, 0, len(bodies))
for i, body := range bodies {
grpcBodies = append(grpcBodies, &execution.BlockBody{
BlockHash: gointerfaces.ConvertHashToH256(blockHashes[i]),
BlockNumber: blockNumbers[i],
Transactions: body.Transactions,
Withdrawals: engine_types.ConvertWithdrawalsToRpc(body.Withdrawals),
})
}
_, err := ec.client.InsertBodies(ec.ctx, &execution.InsertBodiesRequest{Bodies: grpcBodies})
return err
}
// InsertExecutionPayloads insert a segment of execution payloads
func (ec *ExecutionClient) InsertExecutionPayloads(payloads []*cltypes.Eth1Block) error {
headers := make([]*types.Header, 0, len(payloads))
bodies := make([]*types.RawBody, 0, len(payloads))
blockHashes := make([]libcommon.Hash, 0, len(payloads))
blockNumbers := make([]uint64, 0, len(payloads))
for _, payload := range payloads {
rlpHeader, err := payload.RlpHeader()
if err != nil {
return err
}
headers = append(headers, rlpHeader)
bodies = append(bodies, payload.Body())
blockHashes = append(blockHashes, payload.BlockHash)
blockNumbers = append(blockNumbers, payload.BlockNumber)
}
if err := ec.InsertHeaders(headers); err != nil {
return err
}
return ec.InsertBodies(bodies, blockHashes, blockNumbers)
}
func (ec *ExecutionClient) ForkChoiceUpdate(headHash libcommon.Hash) (*execution.ForkChoiceReceipt, error) {
log.Debug("[ExecutionClientRpc] Calling EL", "method", rpc_helper.ForkChoiceUpdatedV1)
return ec.client.UpdateForkChoice(ec.ctx, &execution.ForkChoice{
HeadBlockHash: gointerfaces.ConvertHashToH256(headHash),
Timeout: uint64(fcuTimeout.Milliseconds()),
})
}
func (ec *ExecutionClient) IsCanonical(hash libcommon.Hash) (bool, error) {
resp, err := ec.client.IsCanonicalHash(ec.ctx, gointerfaces.ConvertHashToH256(hash))
if err != nil {
return false, err
}
return resp.Canonical, nil
}
func (ec *ExecutionClient) ReadHeader(number uint64, blockHash libcommon.Hash) (*types.Header, error) {
resp, err := ec.client.GetHeader(ec.ctx, &execution.GetSegmentRequest{
BlockNumber: &number,
BlockHash: gointerfaces.ConvertHashToH256(blockHash),
})
if err != nil {
return nil, err
}
return HeaderRpcToHeader(resp.Header)
}
func (ec *ExecutionClient) ReadExecutionPayload(number uint64, blockHash libcommon.Hash) (*cltypes.Eth1Block, error) {
header, err := ec.ReadHeader(number, blockHash)
if err != nil {
return nil, err
}
body, err := ec.ReadBody(number, blockHash)
if err != nil {
return nil, err
}
return cltypes.NewEth1BlockFromHeaderAndBody(header, body), nil
}
func (ec *ExecutionClient) ReadBody(number uint64, blockHash libcommon.Hash) (*types.RawBody, error) {
resp, err := ec.client.GetBody(ec.ctx, &execution.GetSegmentRequest{
BlockNumber: &number,
BlockHash: gointerfaces.ConvertHashToH256(blockHash),
})
if err != nil {
return nil, err
}
uncles := make([]*types.Header, 0, len(resp.Body.Uncles))
for _, uncle := range resp.Body.Uncles {
h, err := HeaderRpcToHeader(uncle)
if err != nil {
return nil, err
}
uncles = append(uncles, h)
}
return &types.RawBody{
Transactions: resp.Body.Transactions,
Uncles: uncles,
Withdrawals: engine_types.ConvertWithdrawalsFromRpc(resp.Body.Withdrawals),
}, nil
}

View File

@ -1,54 +0,0 @@
package execution_client
import (
"sync"
"github.com/ledgerwatch/erigon/cl/cltypes"
)
const batchSize = 10000
// InsertBatch is a struct for batching and inserting execution payloads.
type InsertBatch struct {
ec *ExecutionClient // The execution client to use for inserting payloads.
payloadBuf []*cltypes.Eth1Block // A buffer for storing execution payloads before they are inserted.
mu sync.Mutex // A mutex for synchronizing access to the payload buffer.
}
// NewInsertBatch creates a new InsertBatch struct with the given execution client.
func NewInsertBatch(ec *ExecutionClient) *InsertBatch {
return &InsertBatch{
ec: ec,
payloadBuf: make([]*cltypes.Eth1Block, 0, batchSize),
}
}
// WriteExecutionPayload adds an execution payload to the payload buffer. If the buffer
// has reached the batch size, the payloads in the buffer are inserted using the
// execution client.
func (b *InsertBatch) WriteExecutionPayload(payload *cltypes.Eth1Block) error {
b.mu.Lock()
defer b.mu.Unlock()
b.payloadBuf = append(b.payloadBuf, payload)
if len(b.payloadBuf) >= batchSize {
if err := b.Flush(); err != nil {
return err
}
}
return nil
}
// Flush inserts the execution payloads in the payload buffer using the execution client.
func (b *InsertBatch) Flush() error {
b.mu.Lock()
defer b.mu.Unlock()
if len(b.payloadBuf) == 0 {
return nil
}
if err := b.ec.InsertExecutionPayloads(b.payloadBuf); err != nil {
return err
}
b.payloadBuf = b.payloadBuf[:0] // Clear the payload buffer.
return nil
}

View File

@ -36,7 +36,7 @@ func TestForkChoiceBasic(t *testing.T) {
expectedCheckpoint := solid.NewCheckpointFromParameters(libcommon.HexToHash("0x564d76d91f66c1fb2977484a6184efda2e1c26dd01992e048353230e10f83201"), 0)
// Decode test blocks
block0x3a, block0xc2, block0xd4 := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}
block0x3a, block0xc2, block0xd4 := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig), cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig), cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
require.NoError(t, utils.DecodeSSZSnappy(block0x3a, block3aEncoded, int(clparams.AltairVersion)))
require.NoError(t, utils.DecodeSSZSnappy(block0xc2, blockc2Encoded, int(clparams.AltairVersion)))
require.NoError(t, utils.DecodeSSZSnappy(block0xd4, blockd4Encoded, int(clparams.AltairVersion)))

View File

@ -22,7 +22,8 @@ var block2 []byte
var anchor []byte
func TestForkGraph(t *testing.T) {
blockA, blockB, blockC := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}
blockA, blockB, blockC := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig),
cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig), cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
anchorState := state.New(&clparams.MainnetBeaconConfig)
require.NoError(t, utils.DecodeSSZSnappy(blockA, block1, int(clparams.Phase0Version)))
require.NoError(t, utils.DecodeSSZSnappy(blockB, block2, int(clparams.Phase0Version)))

View File

@ -80,7 +80,7 @@ func (g *GossipManager) onRecv(data *sentinel.GossipData, l log.Ctx) error {
var object ssz.Unmarshaler
switch data.Type {
case sentinel.GossipType_BeaconBlockGossipType:
object = &cltypes.SignedBeaconBlock{}
object = cltypes.NewSignedBeaconBlock(g.beaconConfig)
if err := object.DecodeSSZ(common.CopyBytes(data.Data), int(version)); err != nil {
g.sentinel.BanPeer(g.ctx, data.Peer)
l["at"] = "decoding block"

View File

@ -3,8 +3,6 @@ package stages
import (
"context"
"errors"
"fmt"
"sync/atomic"
"time"
"github.com/ledgerwatch/erigon/cl/clparams"
@ -14,20 +12,20 @@ import (
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
"github.com/ledgerwatch/erigon/cl/phase1/execution_client"
"github.com/ledgerwatch/erigon/cl/phase1/forkchoice"
network2 "github.com/ledgerwatch/erigon/cl/phase1/network"
"github.com/ledgerwatch/erigon/cl/rpc"
"github.com/ledgerwatch/erigon/cl/sentinel/peers"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/ledgerwatch/log/v3"
"github.com/spf13/afero"
"golang.org/x/sync/errgroup"
)
type Cfg struct {
rpc *rpc.BeaconRpcP2P
genesisCfg *clparams.GenesisConfig
beaconCfg *clparams.BeaconChainConfig
executionClient *execution_client.ExecutionClient
executionClient *execution_client.ExecutionEngine
state *state.CachingBeaconState
gossipManager *network2.GossipManager
forkChoice *forkchoice.ForkChoiceStore
@ -46,7 +44,7 @@ func ClStagesCfg(
genesisCfg *clparams.GenesisConfig,
beaconCfg *clparams.BeaconChainConfig,
state *state.CachingBeaconState,
executionClient *execution_client.ExecutionClient,
executionClient *execution_client.ExecutionEngine,
gossipManager *network2.GossipManager,
forkChoice *forkchoice.ForkChoiceStore,
dataDirFs afero.Fs,
@ -196,10 +194,10 @@ func ConsensusClStages(ctx context.Context,
}
waitWhenNotEnoughPeers := 3 * time.Second
for {
if peersCount > minPeersForDownload {
if peersCount >= minPeersForDownload {
break
}
logger.Debug("[Caplin] Waiting For Peers", "have", peersCount, "needed", minPeersForDownload, "retryIn", waitWhenNotEnoughPeers)
logger.Info("[Caplin] Waiting For Peers", "have", peersCount, "needed", minPeersForDownload, "retryIn", waitWhenNotEnoughPeers)
time.Sleep(waitWhenNotEnoughPeers)
peersCount, err = cfg.rpc.Peers()
if err != nil {
@ -218,67 +216,26 @@ func ConsensusClStages(ctx context.Context,
return CatchUpBlocks
},
ActionFunc: func(ctx context.Context, logger log.Logger, cfg *Cfg, args Args) error {
totalEpochs := args.targetEpoch - args.seenEpoch
logger = logger.New(
"slot", fmt.Sprintf("%d/%d", args.seenSlot, args.targetSlot),
"epoch", fmt.Sprintf("%d/%d(%d)", args.seenEpoch, args.targetEpoch, (1+args.targetEpoch)*cfg.beaconCfg.SlotsPerEpoch-1),
)
logger.Info("downloading epochs from reqresp")
ctx, cn := context.WithTimeout(ctx, time.Duration(cfg.beaconCfg.SecondsPerSlot*cfg.beaconCfg.SlotsPerEpoch)*time.Second)
defer cn()
counter := atomic.Int64{}
// now we download the missing blocks
chans := make([]chan []*peers.PeeredObject[*cltypes.SignedBeaconBlock], 0, totalEpochs)
ctx, cn = context.WithCancel(ctx)
egg, ctx := errgroup.WithContext(ctx)
egg.SetLimit(3)
defer cn()
for i := args.seenEpoch; i <= args.targetEpoch; i = i + 1 {
startBlock := i * cfg.beaconCfg.SlotsPerEpoch
o := make(chan []*peers.PeeredObject[*cltypes.SignedBeaconBlock], 0)
chans = append(chans, o)
egg.Go(func() error {
blocks, err := rpcSource.GetRange(ctx, startBlock, cfg.beaconCfg.SlotsPerEpoch)
if err != nil {
return err
}
logger.Info("downloading epochs from reqresp", "progress", fmt.Sprintf("%d", int(100*(float64(counter.Add(1))/float64(totalEpochs+1))))+"%")
o <- blocks
return nil
})
}
errchan := make(chan error, 1)
go func() {
defer func() {
errchan <- nil
}()
for _, v := range chans {
select {
case <-ctx.Done():
return
case epochResp := <-v:
for _, block := range epochResp {
if block.Data.Block.Slot <= args.seenSlot {
continue
}
err := processBlock(block, false, false)
if err != nil {
errchan <- err
return
}
}
}
}
}()
go func() {
// if any error, lets just return the error and retry. we will make any progress we did... but we should really make sure all parts succeed when catching up
err := egg.Wait()
logger.Info("[Caplin] Downloading epochs from reqresp", "from", args.seenEpoch, "to", args.targetEpoch)
currentEpoch := args.seenEpoch
MainLoop:
for currentEpoch <= args.targetEpoch {
startBlock := currentEpoch * cfg.beaconCfg.SlotsPerEpoch
blocks, err := rpcSource.GetRange(ctx, startBlock, cfg.beaconCfg.SlotsPerEpoch)
if err != nil {
errchan <- err
return err
}
}()
return <-errchan
logger.Info("[Caplin] Epoch downloaded", "epoch", currentEpoch)
for _, block := range blocks {
if err := processBlock(block, false, true); err != nil {
log.Warn("bad blocks segment received", "err", err)
currentEpoch = utils.Max64(args.seenEpoch, currentEpoch-1)
continue MainLoop
}
}
currentEpoch++
}
return nil
},
},
CatchUpBlocks: {
@ -291,7 +248,7 @@ func ConsensusClStages(ctx context.Context,
},
ActionFunc: func(ctx context.Context, logger log.Logger, cfg *Cfg, args Args) error {
totalRequest := args.targetSlot - args.seenSlot
logger.Info("waiting for blocks...",
logger.Debug("waiting for blocks...",
"seenSlot", args.seenSlot,
"targetSlot", args.targetSlot,
"requestedSlots", totalRequest,
@ -314,6 +271,8 @@ func ConsensusClStages(ctx context.Context,
respCh <- blocks
}()
}
logTimer := time.NewTicker(30 * time.Second)
defer logTimer.Stop()
select {
case err := <-errCh:
return err
@ -322,8 +281,9 @@ func ConsensusClStages(ctx context.Context,
if err := processBlock(block, true, true); err != nil {
return err
}
logger.Info("block processed", "slot", block.Data.Block.Slot)
}
case <-logTimer.C:
logger.Info("[Caplin] Progress", "progress", cfg.forkChoice.HighestSeen(), "from", args.seenEpoch, "to", args.targetSlot)
}
return nil
},
@ -351,7 +311,7 @@ func ConsensusClStages(ctx context.Context,
////////}
// Now check the head
headRoot, _, err := cfg.forkChoice.GetHead()
headRoot, headSlot, err := cfg.forkChoice.GetHead()
if err != nil {
return err
}
@ -359,7 +319,7 @@ func ConsensusClStages(ctx context.Context,
// Do forkchoice if possible
if cfg.forkChoice.Engine() != nil {
finalizedCheckpoint := cfg.forkChoice.FinalizedCheckpoint()
logger.Info("Caplin is sending forkchoice")
logger.Debug("Caplin is sending forkchoice")
// Run forkchoice
if err := cfg.forkChoice.Engine().ForkChoiceUpdate(
cfg.forkChoice.GetEth1Hash(finalizedCheckpoint.BlockRoot()),
@ -369,6 +329,7 @@ func ConsensusClStages(ctx context.Context,
return err
}
}
logger.Info("Imported chain segment", "hash", headRoot, "slot", headSlot)
return nil
},
},
@ -443,7 +404,7 @@ func ConsensusClStages(ctx context.Context,
nextSlot := args.seenSlot + 1
nextSlotTime := utils.GetSlotTime(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot, nextSlot)
nextSlotDur := nextSlotTime.Sub(time.Now())
logger.Info("sleeping until next slot", "slot", nextSlot, "time", nextSlotTime, "dur", nextSlotDur)
logger.Debug("sleeping until next slot", "slot", nextSlot, "time", nextSlotTime, "dur", nextSlotDur)
time.Sleep(nextSlotDur)
return nil
},

View File

@ -112,7 +112,7 @@ func (b *BeaconRpcP2P) sendBlocksRequest(ctx context.Context, topic string, reqD
if err != nil {
return nil, message.Peer.Pid, err
}
responseChunk := &cltypes.SignedBeaconBlock{}
responseChunk := cltypes.NewSignedBeaconBlock(b.beaconConfig)
if err = responseChunk.DecodeSSZ(raw, int(version)); err != nil {
return nil, message.Peer.Pid, err

View File

@ -85,8 +85,8 @@ func addSszTests() {
With("Attestation", getSSZStaticConsensusTest(&solid.Attestation{})).
With("AttestationData", getSSZStaticConsensusTest(solid.AttestationData{})).
With("AttesterSlashing", getSSZStaticConsensusTest(&cltypes.AttesterSlashing{})).
With("BeaconBlock", getSSZStaticConsensusTest(&cltypes.BeaconBlock{})).
With("BeaconBlockBody", getSSZStaticConsensusTest(&cltypes.BeaconBody{})).
With("BeaconBlock", getSSZStaticConsensusTest(cltypes.NewBeaconBlock(&clparams.MainnetBeaconConfig))).
With("BeaconBlockBody", getSSZStaticConsensusTest(cltypes.NewBeaconBody(&clparams.MainnetBeaconConfig))).
With("BeaconBlockHeader", getSSZStaticConsensusTest(&cltypes.BeaconBlockHeader{})).
With("BeaconState", getSSZStaticConsensusTest(state.New(&clparams.MainnetBeaconConfig))).
//With("BlobIdentifier", getSSZStaticConsensusTest(&cltypes.BlobIdentifier{})).
@ -99,7 +99,7 @@ func addSszTests() {
// With("DepositMessage", getSSZStaticConsensusTest(&cltypes.DepositMessage{})).
// With("Eth1Block", getSSZStaticConsensusTest(&cltypes.Eth1Block{})).
With("Eth1Data", getSSZStaticConsensusTest(&cltypes.Eth1Data{})).
With("ExecutionPayload", getSSZStaticConsensusTest(&cltypes.Eth1Block{})).
//With("ExecutionPayload", getSSZStaticConsensusTest(&cltypes.NewEth1Block(mainn))).
With("ExecutionPayloadHeader", getSSZStaticConsensusTest(&cltypes.Eth1Header{})).
With("Fork", getSSZStaticConsensusTest(&cltypes.Fork{})).
//With("ForkData", getSSZStaticConsensusTest(&cltypes.ForkData{})).
@ -115,7 +115,7 @@ func addSszTests() {
// With("PowBlock", getSSZStaticConsensusTest(&cltypes.PowBlock{})). Unimplemented
With("ProposerSlashing", getSSZStaticConsensusTest(&cltypes.ProposerSlashing{})).
// With("SignedAggregateAndProof", getSSZStaticConsensusTest(&cltypes.SignedAggregateAndProof{})).
With("SignedBeaconBlock", getSSZStaticConsensusTest(&cltypes.SignedBeaconBlock{})).
With("SignedBeaconBlock", getSSZStaticConsensusTest(cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig))).
With("SignedBeaconBlockHeader", getSSZStaticConsensusTest(&cltypes.SignedBeaconBlockHeader{})).
//With("SignedBlobSidecar", getSSZStaticConsensusTest(&cltypes.SignedBlobSideCar{})).
With("SignedBLSToExecutionChange", getSSZStaticConsensusTest(&cltypes.SignedBLSToExecutionChange{})).

View File

@ -174,20 +174,9 @@ func (b *ForkChoice) Run(t *testing.T, root fs.FS, c spectest.TestCase) (err err
require.Error(t, err, stepstr)
}
case "on_merge_block":
// on_merge_block is for testing things related to the ethereum "The Merge" event
// this has already happened, so let's just pass these tests
return nil
// blk := &cltypes.SignedBeaconBlock{}
// err := spectest.ReadSsz(root, c.Version(), step.GetPowBlock()+".ssz_snappy", blk)
// require.NoError(t, err, stepstr)
// err = forkStore.OnBlock(blk, true, true)
// if step.GetValid() {
// require.NoError(t, err, stepstr)
// } else {
// require.Error(t, err, stepstr)
// }
case "on_block":
blk := &cltypes.SignedBeaconBlock{}
blk := cltypes.NewSignedBeaconBlock(anchorState.BeaconConfig())
err := spectest.ReadSsz(root, c.Version(), step.GetBlock()+".ssz_snappy", blk)
require.NoError(t, err, stepstr)
err = forkStore.OnBlock(blk, true, true)

View File

@ -6,6 +6,7 @@ import (
"os"
"testing"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
"github.com/ledgerwatch/erigon/cl/cltypes"
@ -124,7 +125,7 @@ func operationBlockHeaderHandler(t *testing.T, root fs.FS, c spectest.TestCase)
if err != nil && !expectedError {
return err
}
block := &cltypes.BeaconBlock{}
block := cltypes.NewBeaconBlock(&clparams.MainnetBeaconConfig)
if err := spectest.ReadSszOld(root, block, c.Version(), blockFileName); err != nil {
return err
}
@ -244,7 +245,7 @@ func operationWithdrawalHandler(t *testing.T, root fs.FS, c spectest.TestCase) e
if err != nil && !expectedError {
return err
}
executionPayload := &cltypes.Eth1Block{}
executionPayload := cltypes.NewEth1Block(c.Version(), &clparams.MainnetBeaconConfig)
if err := spectest.ReadSszOld(root, executionPayload, c.Version(), executionPayloadFileName); err != nil {
return err
}

View File

@ -44,6 +44,7 @@ func getSSZStaticConsensusTest[T unmarshalerMarshalerHashable](ref T) spectest.H
require.NoError(t, err)
encoded, err := utils.DecompressSnappy(snappyEncoded)
require.NoError(t, err)
if err := object.DecodeSSZ(encoded, int(c.Version())); err != nil && !isBeaconState {
return err
}

View File

@ -37,11 +37,11 @@ types such as uint64, []byte, and objects that implement the SizedObjectSSZ inte
It handles both static (fixed size) and dynamic (variable size) objects based on their respective decoding methods and offsets.
*/
func UnmarshalSSZ(buf []byte, version int, schema ...interface{}) (err error) {
defer func() {
if err2 := recover(); err2 != nil {
err = fmt.Errorf("panic while decoding: %v", err2)
}
}()
// defer func() {
// if err2 := recover(); err2 != nil {
// err = fmt.Errorf("panic while decoding: %v", err2)
// }
// }()
position := 0
offsets := []int{}

View File

@ -22,7 +22,7 @@ var capellaState []byte
func TestBlockProcessing(t *testing.T) {
s := state.New(&clparams.MainnetBeaconConfig)
require.NoError(t, utils.DecodeSSZSnappy(s, capellaState, int(clparams.CapellaVersion)))
block := &cltypes.SignedBeaconBlock{}
block := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
require.NoError(t, utils.DecodeSSZSnappy(block, capellaBlock, int(clparams.CapellaVersion)))
require.NoError(t, transition.TransitionState(s, block, true)) // All checks already made in transition state
}

View File

@ -163,7 +163,11 @@ func (m *Migrate) getBlock(ctx *Context, block string) (*cltypes.SignedBeaconBlo
if err != nil {
return nil, err
}
blk := &cltypes.SignedBeaconBlock{}
b, _, err := m.chainCfg.configs()
if err != nil {
return nil, err
}
blk := cltypes.NewSignedBeaconBlock(b)
err = blk.DecodeSSZ(bts, 0)
if err != nil {
return nil, err

View File

@ -1,48 +0,0 @@
package main
import (
"flag"
"net"
"github.com/c2h5oh/datasize"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/mdbx"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/log/v3"
"google.golang.org/grpc"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/turbo/snapshotsync/freezeblocks"
)
func main() {
datadirPtr := flag.String("datadir2", "", "non in-memory db for EL simulation")
flag.Parse()
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StderrHandler))
lis, err := net.Listen("tcp", "127.0.0.1:8989")
if err != nil {
log.Warn("[Exec] could not serve service", "reason", err)
}
maxReceiveSize := 500 * datasize.MB
dirs := datadir.New(*datadirPtr)
s := grpc.NewServer(grpc.MaxRecvMsgSize(int(maxReceiveSize)))
var db kv.RwDB
if *datadirPtr == "" {
db = memdb.New("")
} else {
db, err = mdbx.Open(dirs.DataDir, log.Root(), false)
if err != nil {
log.Error("Could not open database", "err", err)
return
}
}
blockReader := freezeblocks.NewBlockReader(freezeblocks.NewRoSnapshots(ethconfig.BlocksFreezing{Enabled: false}, "", log.New()))
execution.RegisterExecutionServer(s, NewEth1Execution(db, blockReader))
log.Info("Serving mock Execution layer.")
if err := s.Serve(lis); err != nil {
log.Error("failed to serve", "err", err)
}
}

View File

@ -1,314 +0,0 @@
package main
import (
"context"
"encoding/binary"
"fmt"
"math/big"
"sync"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/common"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/turbo/engineapi/engine_types"
"github.com/ledgerwatch/erigon/turbo/services"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/types"
)
type Eth1Execution struct {
execution.UnimplementedExecutionServer
db kv.RwDB
blockReader services.FullBlockReader
mu sync.Mutex
}
func NewEth1Execution(db kv.RwDB, blockReader services.FullBlockReader) *Eth1Execution {
return &Eth1Execution{
db: db,
blockReader: blockReader,
}
}
func (e *Eth1Execution) InsertHeaders(ctx context.Context, req *execution.InsertHeadersRequest) (*execution.InsertionResult, error) {
e.mu.Lock()
defer e.mu.Unlock()
tx, err := e.db.BeginRw(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
for _, header := range req.Headers {
h, err := HeaderRpcToHeader(header)
if err != nil {
return nil, err
}
if err := rawdb.WriteHeader(tx, h); err != nil {
return nil, err
}
}
return &execution.InsertionResult{
Result: execution.ExecutionStatus_Success,
}, tx.Commit()
}
func (e *Eth1Execution) InsertBodies(ctx context.Context, req *execution.InsertBodiesRequest) (*execution.InsertionResult, error) {
e.mu.Lock()
defer e.mu.Unlock()
tx, err := e.db.BeginRw(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
for _, body := range req.Bodies {
uncles := make([]*types.Header, 0, len(body.Uncles))
for _, uncle := range body.Uncles {
h, err := HeaderRpcToHeader(uncle)
if err != nil {
return nil, err
}
uncles = append(uncles, h)
}
// Withdrawals processing
withdrawals := make([]*types.Withdrawal, 0, len(body.Withdrawals))
for _, withdrawal := range body.Withdrawals {
withdrawals = append(withdrawals, &types.Withdrawal{
Index: withdrawal.Index,
Validator: withdrawal.ValidatorIndex,
Address: gointerfaces.ConvertH160toAddress(withdrawal.Address),
Amount: withdrawal.Amount,
})
}
if _, err := rawdb.WriteRawBodyIfNotExists(tx, gointerfaces.ConvertH256ToHash(body.BlockHash),
body.BlockNumber, &types.RawBody{
Transactions: body.Transactions,
Uncles: uncles,
Withdrawals: withdrawals,
}); err != nil {
return nil, err
}
}
return &execution.InsertionResult{
Result: execution.ExecutionStatus_Success,
}, tx.Commit()
}
type canonicalEntry struct {
hash libcommon.Hash
number uint64
}
func (e *Eth1Execution) UpdateForkChoice(ctx context.Context, fcu *execution.ForkChoice) (*execution.ForkChoiceReceipt, error) {
e.mu.Lock()
defer e.mu.Unlock()
return &execution.ForkChoiceReceipt{
LatestValidHash: fcu.HeadBlockHash,
Status: execution.ExecutionStatus_Success,
}, nil
}
func (e *Eth1Execution) GetHeader(ctx context.Context, req *execution.GetSegmentRequest) (*execution.GetHeaderResponse, error) {
e.mu.Lock()
defer e.mu.Unlock()
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
// Retrieve header
var header *types.Header
if req.BlockHash != nil && req.BlockNumber != nil {
blockHash := gointerfaces.ConvertH256ToHash(req.BlockHash)
header, err = e.blockReader.Header(ctx, tx, blockHash, *req.BlockNumber)
if err != nil {
return nil, err
}
} else if req.BlockHash != nil {
blockHash := gointerfaces.ConvertH256ToHash(req.BlockHash)
header, err = e.blockReader.HeaderByHash(ctx, tx, blockHash)
if err != nil {
return nil, err
}
} else if req.BlockNumber != nil {
header, err = e.blockReader.HeaderByNumber(ctx, tx, *req.BlockNumber)
if err != nil {
return nil, err
}
}
if err != nil {
return nil, err
}
// Got nothing? return nothing :)
if header == nil {
return &execution.GetHeaderResponse{}, nil
}
return &execution.GetHeaderResponse{
Header: HeaderToHeaderRPC(header),
}, nil
}
func (e *Eth1Execution) GetBody(ctx context.Context, req *execution.GetSegmentRequest) (*execution.GetBodyResponse, error) {
e.mu.Lock()
defer e.mu.Unlock()
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
// Retrieve header
var body *types.Body
if req.BlockHash != nil && req.BlockNumber != nil {
blockHash := gointerfaces.ConvertH256ToHash(req.BlockHash)
if ok, _, err := rawdb.IsCanonicalHashDeprecated(tx, blockHash); err != nil {
return nil, err
} else if ok {
body, err = e.blockReader.BodyWithTransactions(ctx, tx, blockHash, *req.BlockNumber)
if err != nil {
return nil, err
}
}
} else if req.BlockHash != nil {
blockHash := gointerfaces.ConvertH256ToHash(req.BlockHash)
ok, blockNumber, err := rawdb.IsCanonicalHashDeprecated(tx, blockHash)
if err != nil {
return nil, err
}
if ok {
body, err = e.blockReader.BodyWithTransactions(ctx, tx, blockHash, *blockNumber)
if err != nil {
return nil, err
}
}
}
if err != nil {
return nil, err
}
if body == nil {
return nil, nil
}
encodedTransactions, err := types.MarshalTransactionsBinary(body.Transactions)
if err != nil {
return nil, err
}
rpcWithdrawals := engine_types.ConvertWithdrawalsToRpc(body.Withdrawals)
unclesRpc := make([]*execution.Header, 0, len(body.Uncles))
for _, uncle := range body.Uncles {
unclesRpc = append(unclesRpc, HeaderToHeaderRPC(uncle))
}
return &execution.GetBodyResponse{
Body: &execution.BlockBody{
Transactions: encodedTransactions,
Withdrawals: rpcWithdrawals,
Uncles: unclesRpc,
},
}, nil
}
func (e *Eth1Execution) IsCanonicalHash(ctx context.Context, req *types2.H256) (*execution.IsCanonicalResponse, error) {
e.mu.Lock()
defer e.mu.Unlock()
return &execution.IsCanonicalResponse{Canonical: true}, nil
}
func (e *Eth1Execution) GetHeaderHashNumber(ctx context.Context, req *types2.H256) (*execution.GetHeaderHashNumberResponse, error) {
e.mu.Lock()
defer e.mu.Unlock()
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
return &execution.GetHeaderHashNumberResponse{
BlockNumber: rawdb.ReadHeaderNumber(tx, gointerfaces.ConvertH256ToHash(req)),
}, nil
}
func HeaderRpcToHeader(header *execution.Header) (*types.Header, error) {
var blockNonce types.BlockNonce
binary.BigEndian.PutUint64(blockNonce[:], header.Nonce)
var baseFee *big.Int
var withdrawalHash *common.Hash
if header.BaseFeePerGas != nil {
baseFee = gointerfaces.ConvertH256ToUint256Int(header.BaseFeePerGas).ToBig()
}
if header.WithdrawalHash != nil {
withdrawalHash = new(libcommon.Hash)
*withdrawalHash = gointerfaces.ConvertH256ToHash(header.WithdrawalHash)
}
h := &types.Header{
ParentHash: gointerfaces.ConvertH256ToHash(header.ParentHash),
UncleHash: gointerfaces.ConvertH256ToHash(header.OmmerHash),
Coinbase: gointerfaces.ConvertH160toAddress(header.Coinbase),
Root: gointerfaces.ConvertH256ToHash(header.StateRoot),
TxHash: gointerfaces.ConvertH256ToHash(header.TransactionHash),
ReceiptHash: gointerfaces.ConvertH256ToHash(header.ReceiptRoot),
Bloom: gointerfaces.ConvertH2048ToBloom(header.LogsBloom),
Difficulty: gointerfaces.ConvertH256ToUint256Int(header.Difficulty).ToBig(),
Number: big.NewInt(int64(header.BlockNumber)),
GasLimit: header.GasLimit,
GasUsed: header.GasUsed,
Time: header.Timestamp,
Extra: header.ExtraData,
MixDigest: gointerfaces.ConvertH256ToHash(header.PrevRandao),
Nonce: blockNonce,
BaseFee: baseFee,
WithdrawalsHash: withdrawalHash,
}
blockHash := gointerfaces.ConvertH256ToHash(header.BlockHash)
if blockHash != h.Hash() {
return nil, fmt.Errorf("block %d, %x has invalid hash. expected: %x", header.BlockNumber, h.Hash(), blockHash)
}
return types.CopyHeader(h), nil
}
func HeaderToHeaderRPC(header *types.Header) *execution.Header {
difficulty := new(uint256.Int)
difficulty.SetFromBig(header.Difficulty)
var baseFeeReply *types2.H256
if header.BaseFee != nil {
var baseFee uint256.Int
baseFee.SetFromBig(header.BaseFee)
baseFeeReply = gointerfaces.ConvertUint256IntToH256(&baseFee)
}
var withdrawalHashReply *types2.H256
if header.WithdrawalsHash != nil {
withdrawalHashReply = gointerfaces.ConvertHashToH256(*header.WithdrawalsHash)
}
return &execution.Header{
ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash),
Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase),
StateRoot: gointerfaces.ConvertHashToH256(header.Root),
TransactionHash: gointerfaces.ConvertHashToH256(header.TxHash),
LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]),
ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash),
PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest),
BlockNumber: header.Number.Uint64(),
Nonce: header.Nonce.Uint64(),
GasLimit: header.GasLimit,
GasUsed: header.GasUsed,
Timestamp: header.Time,
ExtraData: header.Extra,
Difficulty: gointerfaces.ConvertUint256IntToH256(difficulty),
BlockHash: gointerfaces.ConvertHashToH256(header.Hash()),
OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash),
BaseFeePerGas: baseFeeReply,
WithdrawalHash: withdrawalHashReply,
}
}

View File

@ -115,7 +115,6 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) {
cfg.Addr = ctx.String(flags.SentinelDiscoveryAddr.Name)
cfg.LogLvl = ctx.Uint(logging.LogVerbosityFlag.Name)
fmt.Println(cfg.LogLvl)
if cfg.LogLvl == uint(log.LvlInfo) || cfg.LogLvl == 0 {
cfg.LogLvl = uint(log.LvlDebug)
}
@ -125,7 +124,6 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) {
cfg.CheckpointUri = ctx.String(flags.CheckpointSyncUrlFlag.Name)
} else {
cfg.CheckpointUri = clparams.GetCheckpointSyncEndpoint(cfg.NetworkType)
fmt.Println(cfg.CheckpointUri)
}
cfg.Chaindata = ctx.String(flags.ChaindataFlag.Name)
cfg.BeaconDataCfg = rawdb.BeaconDataConfigurations[ctx.String(flags.BeaconDBModeFlag.Name)]

View File

@ -3,6 +3,7 @@ package handshake
import (
"bytes"
"context"
"fmt"
"sync"
"github.com/ledgerwatch/erigon/cl/clparams"
@ -88,6 +89,7 @@ func (h *HandShaker) ValidatePeer(id peer.ID) bool {
if err != nil {
return false
}
fmt.Println(responseStatus.ForkDigest)
fmt.Println(forkDigest)
return responseStatus.ForkDigest == forkDigest
}

View File

@ -36,6 +36,7 @@ var MainnetBootnodes = []string{
// Sepolia test network.
var SepoliaBootnodes = []string{
// EF DevOps
"enode://4e5e92199ee224a01932a377160aa432f31d0b351f84ab413a8e0a42f4f36476f8fb1cbe914af0d9aef0d51665c214cf653c651c4bbd9d5550a934f241f1682b@138.197.51.181:30303", // sepolia-bootnode-1-nyc3
"enode://143e11fb766781d22d92a2e33f8f104cddae4411a122295ed1fdb6638de96a6ce65f5b7c964ba3763bba27961738fef7d3ecc739268f3e5e771fb4c87b6234ba@146.190.1.103:30303", // sepolia-bootnode-1-sfo3
"enode://8b61dc2d06c3f96fddcbebb0efb29d60d3598650275dc469c22229d3e5620369b0d3dedafd929835fe7f489618f19f456fe7c0df572bf2d914a9f4e006f783a9@170.64.250.88:30303", // sepolia-bootnode-1-syd1

View File

@ -74,7 +74,7 @@ func ReadBlock(root fs.FS, version clparams.StateVersion, index int) (*cltypes.S
if err != nil {
return nil, err
}
blk := &cltypes.SignedBeaconBlock{}
blk := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
if err = utils.DecodeSSZSnappy(blk, blockBytes, int(version)); err != nil {
return nil, err
}
@ -91,7 +91,7 @@ func ReadAnchorBlock(root fs.FS, version clparams.StateVersion, name string) (*c
if err != nil {
return nil, err
}
blk := &cltypes.BeaconBlock{}
blk := cltypes.NewBeaconBlock(&clparams.MainnetBeaconConfig)
if err = utils.DecodeSSZSnappy(blk, blockBytes, int(version)); err != nil {
return nil, err
}
@ -126,7 +126,7 @@ func ReadBlocks(root fs.FS, version clparams.StateVersion) ([]*cltypes.SignedBea
if err != nil {
break
}
blk := &cltypes.SignedBeaconBlock{}
blk := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig)
if err = utils.DecodeSSZSnappy(blk, blockBytes, int(version)); err != nil {
return nil, err
}