mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
Added blocks API and attestations API (#8279)
This commit is contained in:
parent
4bec348e62
commit
a95914df26
@ -4,12 +4,14 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon/cl/clparams"
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes"
|
||||
"github.com/ledgerwatch/erigon/cl/persistence/beacon_indicies"
|
||||
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy"
|
||||
)
|
||||
|
||||
type headerResponse struct {
|
||||
@ -57,8 +59,119 @@ func (a *ApiHandler) rootFromBlockId(ctx context.Context, tx *sql.Tx, blockId *s
|
||||
return
|
||||
}
|
||||
|
||||
func (a *ApiHandler) getBlock(w http.ResponseWriter, r *http.Request) {
|
||||
func (a *ApiHandler) getBlock(r *http.Request) (data any, finalized *bool, version *clparams.StateVersion, httpStatus int, err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
blockId *segmentID
|
||||
root libcommon.Hash
|
||||
blkHeader *cltypes.SignedBeaconBlockHeader
|
||||
blockReader io.ReadCloser
|
||||
isCanonical bool
|
||||
)
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
tx, err = a.indiciesDB.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
httpStatus = http.StatusInternalServerError
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
blockId, err = blockIdFromRequest(r)
|
||||
if err != nil {
|
||||
fmt.Println("A")
|
||||
httpStatus = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
root, httpStatus, err = a.rootFromBlockId(ctx, tx, blockId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
blkHeader, isCanonical, err = beacon_indicies.ReadSignedHeaderByBlockRoot(ctx, tx, root)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if blkHeader == nil {
|
||||
httpStatus = http.StatusNotFound
|
||||
err = fmt.Errorf("block not found %x", root)
|
||||
return
|
||||
}
|
||||
|
||||
blockReader, err = a.blockSource.BlockReader(ctx, blkHeader.Header.Slot, root)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer blockReader.Close()
|
||||
blk := cltypes.NewSignedBeaconBlock(a.beaconChainCfg)
|
||||
version = new(clparams.StateVersion)
|
||||
*version = a.beaconChainCfg.GetCurrentStateVersion(blkHeader.Header.Slot / a.beaconChainCfg.SlotsPerEpoch)
|
||||
if err = ssz_snappy.DecodeAndReadNoForkDigest(blockReader, blk, *version); err != nil {
|
||||
return
|
||||
}
|
||||
data = blk
|
||||
finalized = new(bool)
|
||||
httpStatus = http.StatusAccepted
|
||||
*finalized = isCanonical && blkHeader.Header.Slot <= a.forkchoiceStore.FinalizedSlot()
|
||||
return
|
||||
}
|
||||
|
||||
func (a *ApiHandler) getBlockAttestations(r *http.Request) (data any, finalized *bool, version *clparams.StateVersion, httpStatus int, err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
blockId *segmentID
|
||||
root libcommon.Hash
|
||||
blkHeader *cltypes.SignedBeaconBlockHeader
|
||||
blockReader io.ReadCloser
|
||||
isCanonical bool
|
||||
)
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
tx, err = a.indiciesDB.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
httpStatus = http.StatusInternalServerError
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
blockId, err = blockIdFromRequest(r)
|
||||
if err != nil {
|
||||
fmt.Println("A")
|
||||
httpStatus = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
root, httpStatus, err = a.rootFromBlockId(ctx, tx, blockId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
blkHeader, isCanonical, err = beacon_indicies.ReadSignedHeaderByBlockRoot(ctx, tx, root)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if blkHeader == nil {
|
||||
httpStatus = http.StatusNotFound
|
||||
err = fmt.Errorf("block not found %x", root)
|
||||
return
|
||||
}
|
||||
|
||||
blockReader, err = a.blockSource.BlockReader(ctx, blkHeader.Header.Slot, root)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer blockReader.Close()
|
||||
blk := cltypes.NewSignedBeaconBlock(a.beaconChainCfg)
|
||||
version = new(clparams.StateVersion)
|
||||
*version = a.beaconChainCfg.GetCurrentStateVersion(blkHeader.Header.Slot / a.beaconChainCfg.SlotsPerEpoch)
|
||||
if err = ssz_snappy.DecodeAndReadNoForkDigest(blockReader, blk, *version); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data = blk.Block.Body.Attestations
|
||||
finalized = new(bool)
|
||||
httpStatus = http.StatusAccepted
|
||||
*finalized = isCanonical && blkHeader.Header.Slot <= a.forkchoiceStore.FinalizedSlot()
|
||||
return
|
||||
}
|
||||
|
||||
func (a *ApiHandler) getBlockRoot(r *http.Request) (data any, finalized *bool, version *clparams.StateVersion, httpStatus int, err error) {
|
||||
|
@ -15,14 +15,14 @@ type ApiHandler struct {
|
||||
o sync.Once
|
||||
mux chi.Router
|
||||
|
||||
blockSource persistence.BlockSource
|
||||
blockSource persistence.RawBeaconBlockChain
|
||||
indiciesDB *sql.DB
|
||||
genesisCfg *clparams.GenesisConfig
|
||||
beaconChainCfg *clparams.BeaconChainConfig
|
||||
forkchoiceStore forkchoice.ForkChoiceStorage
|
||||
}
|
||||
|
||||
func NewApiHandler(genesisConfig *clparams.GenesisConfig, beaconChainConfig *clparams.BeaconChainConfig, source persistence.BlockSource, indiciesDB *sql.DB, forkchoiceStore forkchoice.ForkChoiceStorage) *ApiHandler {
|
||||
func NewApiHandler(genesisConfig *clparams.GenesisConfig, beaconChainConfig *clparams.BeaconChainConfig, source persistence.RawBeaconBlockChain, indiciesDB *sql.DB, forkchoiceStore forkchoice.ForkChoiceStorage) *ApiHandler {
|
||||
return &ApiHandler{o: sync.Once{}, genesisCfg: genesisConfig, beaconChainCfg: beaconChainConfig, indiciesDB: indiciesDB, blockSource: source, forkchoiceStore: forkchoiceStore}
|
||||
}
|
||||
|
||||
@ -46,8 +46,8 @@ func (a *ApiHandler) init() {
|
||||
})
|
||||
r.Route("/blocks", func(r chi.Router) {
|
||||
r.Post("/", nil)
|
||||
r.Get("/{block_id}", a.getBlock)
|
||||
r.Get("/{block_id}/attestations", beaconHandlerWrapper(a.getBlockRoot))
|
||||
r.Get("/{block_id}", beaconHandlerWrapper(a.getBlock))
|
||||
r.Get("/{block_id}/attestations", beaconHandlerWrapper(a.getBlockAttestations))
|
||||
r.Get("/{block_id}/root", beaconHandlerWrapper(a.getBlockRoot))
|
||||
})
|
||||
r.Get("/genesis", beaconHandlerWrapper(a.getGenesis))
|
||||
|
@ -50,9 +50,9 @@ func NewAttestionFromParameters(
|
||||
|
||||
func (a Attestation) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
AggregationBits hexutility.Bytes
|
||||
Signature libcommon.Bytes96
|
||||
Data AttestationData
|
||||
AggregationBits hexutility.Bytes `json:"aggregation_bits"`
|
||||
Signature libcommon.Bytes96 `json:"signature"`
|
||||
Data AttestationData `json:"data"`
|
||||
}{
|
||||
AggregationBits: a.aggregationBitsBuffer,
|
||||
Signature: a.Signature(),
|
||||
@ -62,9 +62,9 @@ func (a Attestation) MarshalJSON() ([]byte, error) {
|
||||
|
||||
func (a *Attestation) UnmarshalJSON(buf []byte) error {
|
||||
var tmp struct {
|
||||
AggregationBits hexutility.Bytes
|
||||
Signature libcommon.Bytes96
|
||||
Data AttestationData
|
||||
AggregationBits hexutility.Bytes `json:"aggregation_bits"`
|
||||
Signature libcommon.Bytes96 `json:"signature"`
|
||||
Data AttestationData `json:"data"`
|
||||
}
|
||||
if err := json.Unmarshal(buf, &tmp); err != nil {
|
||||
return err
|
||||
|
@ -40,11 +40,11 @@ func NewAttestionDataFromParameters(
|
||||
|
||||
func (a AttestationData) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
Slot uint64
|
||||
Index uint64
|
||||
BeaconBlockRoot libcommon.Hash
|
||||
Source Checkpoint
|
||||
Target Checkpoint
|
||||
Slot uint64 `json:"slot"`
|
||||
Index uint64 `json:"index"`
|
||||
BeaconBlockRoot libcommon.Hash `json:"beacon_block_root"`
|
||||
Source Checkpoint `json:"source"`
|
||||
Target Checkpoint `json:"target"`
|
||||
}{
|
||||
Slot: a.Slot(),
|
||||
BeaconBlockRoot: a.BeaconBlockRoot(),
|
||||
@ -56,11 +56,11 @@ func (a AttestationData) MarshalJSON() ([]byte, error) {
|
||||
|
||||
func (a AttestationData) UnmarshalJSON(buf []byte) error {
|
||||
var tmp struct {
|
||||
Slot uint64
|
||||
Index uint64
|
||||
BeaconBlockRoot libcommon.Hash
|
||||
Source Checkpoint
|
||||
Target Checkpoint
|
||||
Slot uint64 `json:"slot"`
|
||||
Index uint64 `json:"index"`
|
||||
BeaconBlockRoot libcommon.Hash `json:"beacon_block_root"`
|
||||
Source Checkpoint `json:"source"`
|
||||
Target Checkpoint `json:"target"`
|
||||
}
|
||||
if err := json.Unmarshal(buf, &tmp); err != nil {
|
||||
return err
|
||||
|
@ -35,15 +35,15 @@ func NewCheckpoint() Checkpoint {
|
||||
|
||||
func (c Checkpoint) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
Epoch uint64
|
||||
Root libcommon.Hash
|
||||
Epoch uint64 `json:"epoch"`
|
||||
Root libcommon.Hash `json:"root"`
|
||||
}{Epoch: c.Epoch(), Root: c.BlockRoot()})
|
||||
}
|
||||
|
||||
func (c Checkpoint) UnmarshalJSON(buf []byte) error {
|
||||
var tmp struct {
|
||||
Epoch uint64
|
||||
Root libcommon.Hash
|
||||
Epoch uint64 `json:"epoch"`
|
||||
Root libcommon.Hash `json:"root"`
|
||||
}
|
||||
if err := json.Unmarshal(buf, &tmp); err != nil {
|
||||
return err
|
||||
|
@ -315,7 +315,7 @@ func ConsensusClStages(ctx context.Context,
|
||||
}
|
||||
currentEpoch++
|
||||
}
|
||||
return nil
|
||||
return tx.Commit()
|
||||
},
|
||||
},
|
||||
CatchUpBlocks: {
|
||||
|
@ -36,6 +36,7 @@ func OpenCaplinDatabase(ctx context.Context,
|
||||
) (persistence.BeaconChainDatabase, *sql.DB, error) {
|
||||
dataDirIndexer := path.Join(dbPath, "beacon_indicies")
|
||||
os.Remove(dataDirIndexer)
|
||||
os.MkdirAll(dbPath, 0700)
|
||||
|
||||
db, err := sql.Open("sqlite", dataDirIndexer)
|
||||
if err != nil {
|
||||
@ -69,7 +70,7 @@ func OpenCaplinDatabase(ctx context.Context,
|
||||
|
||||
func RunCaplinPhase1(ctx context.Context, sentinel sentinel.SentinelClient, engine execution_client.ExecutionEngine,
|
||||
beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, state *state.CachingBeaconState,
|
||||
caplinFreezer freezer.Freezer, db *sql.DB, beaconDB persistence.BeaconChainDatabase, tmpdir string, cfg beacon.RouterConfiguration) error {
|
||||
caplinFreezer freezer.Freezer, db *sql.DB, rawDB persistence.RawBeaconBlockChain, beaconDB persistence.BeaconChainDatabase, tmpdir string, cfg beacon.RouterConfiguration) error {
|
||||
ctx, cn := context.WithCancel(ctx)
|
||||
defer cn()
|
||||
|
||||
@ -113,7 +114,7 @@ func RunCaplinPhase1(ctx context.Context, sentinel sentinel.SentinelClient, engi
|
||||
}
|
||||
|
||||
if cfg.Active {
|
||||
apiHandler := handler.NewApiHandler(genesisConfig, beaconConfig, beaconDB, db, forkChoice)
|
||||
apiHandler := handler.NewApiHandler(genesisConfig, beaconConfig, rawDB, db, forkChoice)
|
||||
go beacon.ListenAndServe(apiHandler, &cfg)
|
||||
log.Info("Beacon API started", "addr", cfg.Address)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cl/beacon"
|
||||
"github.com/ledgerwatch/erigon/cl/freezer"
|
||||
@ -124,11 +125,13 @@ func runCaplinNode(cliCtx *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
beaconDB, sqlDB, err := caplin1.OpenCaplinDatabase(ctx, db_config.DatabaseConfiguration{}, cfg.BeaconCfg, persistence.AferoRawBeaconBlockChainFromOsPath(cfg.BeaconCfg, cfg.Dirs.Tmp), cfg.Dirs.Tmp, executionEngine)
|
||||
caplinDBPath := path.Join(cfg.DataDir, "caplin")
|
||||
rawdb := persistence.AferoRawBeaconBlockChainFromOsPath(cfg.BeaconCfg, caplinDBPath)
|
||||
beaconDB, sqlDB, err := caplin1.OpenCaplinDatabase(ctx, db_config.DefaultDatabaseConfiguration, cfg.BeaconCfg, rawdb, caplinDBPath, executionEngine)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return caplin1.RunCaplinPhase1(ctx, sentinel, executionEngine, cfg.BeaconCfg, cfg.GenesisCfg, state, caplinFreezer, sqlDB, beaconDB, cfg.Dirs.Tmp, beacon.RouterConfiguration{
|
||||
return caplin1.RunCaplinPhase1(ctx, sentinel, executionEngine, cfg.BeaconCfg, cfg.GenesisCfg, state, caplinFreezer, sqlDB, rawdb, beaconDB, cfg.Dirs.Tmp, beacon.RouterConfiguration{
|
||||
Protocol: cfg.BeaconProtocol,
|
||||
Address: cfg.BeaconAddr,
|
||||
ReadTimeTimeout: cfg.BeaconApiReadTimeout,
|
||||
|
@ -790,7 +790,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go caplin1.RunCaplinPhase1(ctx, client, engine, beaconCfg, genesisCfg, state, nil, sqlDb, beaconDB, dirs.Tmp, beacon.RouterConfiguration{Active: false})
|
||||
go caplin1.RunCaplinPhase1(ctx, client, engine, beaconCfg, genesisCfg, state, nil, sqlDb, rawBeaconBlockChainDb, beaconDB, dirs.Tmp, beacon.RouterConfiguration{Active: false})
|
||||
}
|
||||
|
||||
return backend, nil
|
||||
|
Loading…
Reference in New Issue
Block a user