erigon-pulse/turbo/execution/eth1/getters.go
2023-07-15 18:31:15 +02:00

138 lines
5.1 KiB
Go

package eth1
import (
"context"
"errors"
"fmt"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/gointerfaces/execution"
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon/core/rawdb"
)
func (e *EthereumExecutionModule) parseSegmentRequest(ctx context.Context, tx kv.Tx, req *execution.GetSegmentRequest) (blockHash libcommon.Hash, blockNumber uint64, err error) {
switch {
// Case 1: Only hash is given.
case req.BlockHash != nil && req.BlockNumber == nil:
blockHash = gointerfaces.ConvertH256ToHash(req.BlockHash)
blockNumberPtr := rawdb.ReadHeaderNumber(tx, blockHash)
if blockNumberPtr == nil {
err = fmt.Errorf("ethereumExecutionModule.parseSegmentRequest: could not read block: non existent index")
return
}
blockNumber = *blockNumberPtr
case req.BlockHash == nil && req.BlockNumber != nil:
blockNumber = *req.BlockNumber
blockHash, err = e.canonicalHash(ctx, tx, blockNumber)
if err != nil {
err = fmt.Errorf("ethereumExecutionModule.parseSegmentRequest: could not read block %d: %s", blockNumber, err)
return
}
case req.BlockHash != nil && req.BlockNumber != nil:
blockHash = gointerfaces.ConvertH256ToHash(req.BlockHash)
blockNumber = *req.BlockNumber
}
return
}
func (e *EthereumExecutionModule) GetBody(ctx context.Context, req *execution.GetSegmentRequest) (*execution.GetBodyResponse, error) {
// Invalid case: request is invalid.
if req == nil || (req.BlockHash == nil && req.BlockNumber == nil) {
return nil, errors.New("ethereumExecutionModule.GetBody: bad request")
}
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: could not open database: %s", err)
}
defer tx.Rollback()
chainTx, err := e.chainDb.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: could not open database: %s", err)
}
defer chainTx.Rollback()
blockHash, blockNumber, err := e.parseSegmentRequest(ctx, tx, req)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetBody: %s", err)
}
body, err := e.getBody(ctx, chainTx, tx, blockHash, blockNumber)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetBody: coild not read body: %s", err)
}
if body == nil {
return &execution.GetBodyResponse{Body: nil}, nil
}
rawBody := body.RawBody()
return &execution.GetBodyResponse{Body: ConvertRawBlockBodyToRpc(rawBody, blockNumber, blockHash)}, nil
}
func (e *EthereumExecutionModule) GetHeader(ctx context.Context, req *execution.GetSegmentRequest) (*execution.GetHeaderResponse, error) {
// Invalid case: request is invalid.
if req == nil || (req.BlockHash == nil && req.BlockNumber == nil) {
return nil, errors.New("ethereumExecutionModule.GetHeader: bad request")
}
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: could not open database: %s", err)
}
defer tx.Rollback()
chainTx, err := e.chainDb.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: could not open database: %s", err)
}
defer chainTx.Rollback()
blockHash, blockNumber, err := e.parseSegmentRequest(ctx, tx, req)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: %s", err)
}
header, err := e.getHeader(ctx, chainTx, tx, blockHash, blockNumber)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetHeader: coild not read body: %s", err)
}
if header == nil {
return &execution.GetHeaderResponse{Header: nil}, nil
}
return &execution.GetHeaderResponse{Header: HeaderToHeaderRPC(header)}, nil
}
func (e *EthereumExecutionModule) GetHeaderHashNumber(ctx context.Context, req *types2.H256) (*execution.GetHeaderHashNumberResponse, error) {
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.GetBody: could not open database: %s", err)
}
defer tx.Rollback()
blockNumber := rawdb.ReadHeaderNumber(tx, gointerfaces.ConvertH256ToHash(req))
if blockNumber == nil {
return nil, fmt.Errorf("ethereumExecutionModule.parseSegmentRequest: could not read block: non existent index")
}
return &execution.GetHeaderHashNumberResponse{BlockNumber: blockNumber}, nil
}
func (e *EthereumExecutionModule) CanonicalHash(ctx context.Context, req *types2.H256) (*execution.IsCanonicalResponse, error) {
tx, err := e.db.BeginRo(ctx)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.CanonicalHash: could not open database: %s", err)
}
defer tx.Rollback()
blockHash := gointerfaces.ConvertH256ToHash(req)
blockNumber := rawdb.ReadHeaderNumber(tx, blockHash)
if blockNumber == nil {
return nil, fmt.Errorf("ethereumExecutionModule.CanonicalHash: could not read block: non existent index")
}
expectedHash, err := e.canonicalHash(ctx, tx, *blockNumber)
if err != nil {
return nil, fmt.Errorf("ethereumExecutionModule.CanonicalHash: could not read canonical hash")
}
return &execution.IsCanonicalResponse{Canonical: expectedHash == blockHash}, nil
}