Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ linters:
- nolintlint
- nakedret
- prealloc
- revive
- staticcheck
- structcheck
- stylecheck
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ module github.com/ethpandaops/checkpointz

go 1.17

replace github.com/attestantio/go-eth2-client v0.15.7 => github.com/samcm/go-eth2-client v0.15.8

require (
github.com/attestantio/go-eth2-client v0.15.2
github.com/attestantio/go-eth2-client v0.15.7
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
github.com/creasty/defaults v1.6.0
github.com/ethpandaops/beacon v0.21.0
github.com/ethpandaops/beacon v0.24.0
github.com/go-co-op/gocron v1.18.0
github.com/julienschmidt/httprouter v1.3.0
github.com/pkg/errors v0.9.1
Expand Down
23 changes: 7 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/attestantio/go-eth2-client v0.14.5 h1:pKOTcbv9KOiVixVKM5Cr8nJrjD1VOIWmrlNFO0YtF64=
github.com/attestantio/go-eth2-client v0.14.5/go.mod h1:5kLLzdlyPGboWr8tAwnG/4Kpi43BHd/HWp++WmmP6Ws=
github.com/attestantio/go-eth2-client v0.15.2 h1:4EYeA5IBSBypkUMhkkFALzMddaFDdb5PvCl7ORXEl6w=
github.com/attestantio/go-eth2-client v0.15.2/go.mod h1:/Oh6YTuHmHhgLN/ZnQRKHGc7HdIzGlDkI2vjNZvOsvA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -70,10 +66,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethpandaops/beacon v0.20.0 h1:z389nMmzVYbPhP4+ahcaezqr9SivolWhnCYeWVeWFz8=
github.com/ethpandaops/beacon v0.20.0/go.mod h1:fkS2U962xdB6+VwBn+J+DMK8cTgTtzVtjZWtvTKjbuE=
github.com/ethpandaops/beacon v0.21.0 h1:s/088DT9oOYWt/mrDQ+mkhHiyK2wtMAOyE3Voar6nf0=
github.com/ethpandaops/beacon v0.21.0/go.mod h1:fkS2U962xdB6+VwBn+J+DMK8cTgTtzVtjZWtvTKjbuE=
github.com/ethpandaops/beacon v0.24.0 h1:WP0ySKmHgyJWTsVn47zOVEPzZ22FSa/fdkr/iIMmeLM=
github.com/ethpandaops/beacon v0.24.0/go.mod h1:p+PMyAYXro2hgNEMNbCtzLOvzHund9Q9BTPATvf8/SA=
github.com/ethpandaops/ethwallclock v0.2.0 h1:EeFKtZ7v6TAdn/oAh0xaPujD7N4amjBxrWIByraUfLM=
github.com/ethpandaops/ethwallclock v0.2.0/go.mod h1:y0Cu+mhGLlem19vnAV2x0hpFS5KZ7oOi2SWYayv9l24=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
Expand All @@ -83,7 +77,6 @@ github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNP
github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/go-co-op/gocron v1.16.2 h1:p9ghzsN5PqqPyWXYDO2JlvD1DOUNT8pPSyGYC62XBcY=
github.com/go-co-op/gocron v1.16.2/go.mod h1:W/N9G7bntRo5fVQlmjncvqSt74jxCxHfjyHlgcB33T8=
github.com/go-co-op/gocron v1.18.0 h1:SxTyJ5xnSN4byCq7b10LmmszFdxQlSQJod8s3gbnXxA=
github.com/go-co-op/gocron v1.18.0/go.mod h1:sD/a0Aadtw5CpflUJ/lpP9Vfdk979Wl1Sg33HPHg0FY=
Expand Down Expand Up @@ -172,8 +165,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
Expand Down Expand Up @@ -238,14 +229,12 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
Expand Down Expand Up @@ -279,29 +268,31 @@ github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+
github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs=
github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/samcm/go-eth2-client v0.15.8 h1:V2gwKrnxImQE/Fmy9a2rzNRj0GQqnhP74Rgfm067HTA=
github.com/samcm/go-eth2-client v0.15.8/go.mod h1:PLRKnILnr63V3yl2VagBqnhVRFBWc0V+JhQSsXQaSwQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
18 changes: 18 additions & 0 deletions pkg/api/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (h *Handler) Register(ctx context.Context, router *httprouter.Router) error
router.GET("/eth/v1/beacon/genesis", h.wrappedHandler(h.handleEthV1BeaconGenesis))
router.GET("/eth/v1/beacon/blocks/:block_id/root", h.wrappedHandler(h.handleEthV1BeaconBlocksRoot))
router.GET("/eth/v1/beacon/states/:state_id/finality_checkpoints", h.wrappedHandler(h.handleEthV1BeaconStatesFinalityCheckpoints))
router.GET("/eth/v1/beacon/deposit_snapshot", h.wrappedHandler(h.handleEthV1BeaconDepositSnapshot))

router.GET("/eth/v1/config/spec", h.wrappedHandler(h.handleEthV1ConfigSpec))
router.GET("/eth/v1/config/deposit_contract", h.wrappedHandler(h.handleEthV1ConfigDepositContract))
Expand Down Expand Up @@ -564,3 +565,20 @@ func (h *Handler) handleEthV1BeaconBlocksRoot(ctx context.Context, r *http.Reque
},
}), nil
}

func (h *Handler) handleEthV1BeaconDepositSnapshot(ctx context.Context, r *http.Request, p httprouter.Params, contentType ContentType) (*HTTPResponse, error) {
if err := ValidateContentType(contentType, []ContentType{ContentTypeJSON}); err != nil {
return NewUnsupportedMediaTypeResponse(nil), err
}

snapshot, err := h.eth.DepositSnapshot(ctx)
if err != nil {
return NewInternalServerErrorResponse(nil), err
}

return NewSuccessResponse(ContentTypeResolvers{
ContentTypeJSON: func() ([]byte, error) {
return json.Marshal(snapshot)
},
}), nil
}
2 changes: 2 additions & 0 deletions pkg/beacon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type CacheConfig struct {
Blocks store.Config `yaml:"blocks" default:"{\"MaxItems\": 200}"`
// States holds the state cache configuration.
States store.Config `yaml:"states" default:"{\"MaxItems\": 5}"`
// DepositSnapshots holds the deposit snapshot cache configuration.
DepositSnapshots store.Config `yaml:"deposit_snapshots" default:"{\"MaxItems\": 50}"`
}

type FrontendConfig struct {
Expand Down
16 changes: 11 additions & 5 deletions pkg/beacon/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ type Default struct {
head *v1.Finality
servingBundle *v1.Finality

blocks *store.Block
states *store.BeaconState
blocks *store.Block
states *store.BeaconState
depositSnapshots *store.DepositSnapshot

spec *state.Spec
genesis *v1.Genesis
Expand Down Expand Up @@ -60,9 +61,10 @@ func NewDefaultProvider(namespace string, log logrus.FieldLogger, nodes []node.C

historicalSlotFailures: make(map[phase0.Slot]int),

broker: emission.NewEmitter(),
blocks: store.NewBlock(log, config.Caches.Blocks, namespace),
states: store.NewBeaconState(log, config.Caches.States, namespace),
broker: emission.NewEmitter(),
blocks: store.NewBlock(log, config.Caches.Blocks, namespace),
states: store.NewBeaconState(log, config.Caches.States, namespace),
depositSnapshots: store.NewDepositSnapshot(log, config.Caches.DepositSnapshots, namespace),

metrics: NewMetrics(namespace + "_beacon"),
}
Expand Down Expand Up @@ -614,3 +616,7 @@ func (d *Default) GetSlotTime(ctx context.Context, slot phase0.Slot) (eth.SlotTi

return eth.CalculateSlotTime(slot, d.genesis.GenesisTime, d.spec.SecondsPerSlot.AsDuration()), nil
}

func (d *Default) GetDepositSnapshot(ctx context.Context, epoch phase0.Epoch) (*types.DepositSnapshot, error) {
return d.depositSnapshots.GetByEpoch(epoch)
}
41 changes: 41 additions & 0 deletions pkg/beacon/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,48 @@ func (d *Default) fetchBundle(ctx context.Context, root phase0.Root, upstream *N
}
}

if slot != phase0.Slot(0) {
epoch := phase0.Epoch(slot / d.spec.SlotsPerEpoch)

// Download and store deposit snapshots
if err := d.downloadAndStoreDepositSnapshot(ctx, epoch, upstream); err != nil {
return nil, fmt.Errorf("failed to download and store deposit snapshot: %w", err)
}
}

d.log.Infof("Successfully fetched bundle from %s", upstream.Config.Name)

return block, nil
}

func (d *Default) downloadAndStoreDepositSnapshot(ctx context.Context, epoch phase0.Epoch, node *Node) error {
// Check if we already have the deposit snapshot.
if _, err := d.depositSnapshots.GetByEpoch(epoch); err == nil {
return nil
}

// Download the deposit snapshot from our upstream.
depositSnapshot, err := node.Beacon.FetchDepositSnapshot(ctx)
if err != nil {
return err
}

if depositSnapshot == nil {
return errors.New("invalid deposit snapshot")
}

// These are small so store them for a month. Max items will most likely purge it before then.
// Mostly just guarding against periods of non-finality; we won't have new items to purge the old ones which
// is a good thing here.
expiresAt := time.Now().Add(672 * time.Hour)

if err := d.depositSnapshots.Add(epoch, depositSnapshot, expiresAt); err != nil {
return fmt.Errorf("failed to store deposit snapshot: %w", err)
}

d.log.
WithFields(logrus.Fields{"epoch": epoch}).
Infof("Downloaded and stored deposit snapshot for epoch %d", epoch)

return nil
}
2 changes: 2 additions & 0 deletions pkg/beacon/finality_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ type FinalityProvider interface {
OperatingMode() OperatingMode
// GetSlotTime returns the wall clock for the given slot.
GetSlotTime(ctx context.Context, slot phase0.Slot) (eth.SlotTime, error)
// GetDepositSnapshot returns the deposit snapshot at the given epoch.
GetDepositSnapshot(ctx context.Context, epoch phase0.Epoch) (*types.DepositSnapshot, error)
}
63 changes: 63 additions & 0 deletions pkg/beacon/store/deposit_snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package store

import (
"errors"
"time"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ethpandaops/beacon/pkg/beacon/api/types"
"github.com/ethpandaops/checkpointz/pkg/cache"
"github.com/ethpandaops/checkpointz/pkg/eth"
"github.com/sirupsen/logrus"
)

type DepositSnapshot struct {
store *cache.TTLMap
log logrus.FieldLogger
}

func NewDepositSnapshot(log logrus.FieldLogger, config Config, namespace string) *DepositSnapshot {
d := &DepositSnapshot{
log: log.WithField("component", "beacon/store/deposit_snapshot"),
store: cache.NewTTLMap(config.MaxItems, "deposit_snapshot", namespace),
}

d.store.OnItemDeleted(func(key string, value interface{}, expiredAt time.Time) {
d.log.WithField("key", key).WithField("expired_at", expiredAt.String()).Debug("Deposit snapshot was deleted from the cache")
})

d.store.EnableMetrics(namespace)

return d
}

func (d *DepositSnapshot) Add(epoch phase0.Epoch, snapshot *types.DepositSnapshot, expiresAt time.Time) error {
d.store.Add(eth.EpochAsString(epoch), snapshot, expiresAt)

d.log.WithFields(
logrus.Fields{
"epoch": eth.EpochAsString(epoch),
"expires_at": expiresAt.String(),
},
).Debug("Added deposit snapshot")

return nil
}

func (d *DepositSnapshot) GetByEpoch(epoch phase0.Epoch) (*types.DepositSnapshot, error) {
data, _, err := d.store.Get(eth.EpochAsString(epoch))
if err != nil {
return nil, err
}

return d.parseSnapshot(data)
}

func (d *DepositSnapshot) parseSnapshot(data interface{}) (*types.DepositSnapshot, error) {
snapshot, ok := data.(*types.DepositSnapshot)
if !ok {
return nil, errors.New("invalid deposit snapshot type")
}

return snapshot, nil
}
27 changes: 27 additions & 0 deletions pkg/service/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,33 @@ func (h *Handler) DepositContract(ctx context.Context) (*DepositContract, error)
}, nil
}

// DepositContract gets the deposit snapshot at the finalized checkpoint.
func (h *Handler) DepositSnapshot(ctx context.Context) (*types.DepositSnapshot, error) {
var err error

const call = "beacon_deposit_snapshot"

h.metrics.ObserveCall(call, "")

defer func() {
if err != nil {
h.metrics.ObserveErrorCall(call, "")
}
}()

finality, err := h.provider.Finalized(ctx)
if err != nil {
return nil, err
}

snapshot, err := h.provider.GetDepositSnapshot(ctx, finality.Finalized.Epoch)
if err != nil {
return nil, err
}

return snapshot, nil
}

// NodeSyncing returns the sync state of the beacon node.
func (h *Handler) NodeSyncing(ctx context.Context) (*v1.SyncState, error) {
var err error
Expand Down