From 4997e2eedbabe09ce459a3d995b8e56a01ceaa6f Mon Sep 17 00:00:00 2001 From: Christopher Tarry Date: Thu, 4 Jan 2024 12:02:58 -0500 Subject: [PATCH] add endpoint to get block by height --- api/client.go | 10 ++++++++-- api/server.go | 18 ++++++++++++++++-- explorer/explorer.go | 6 ++++++ go.mod | 4 ++-- go.sum | 3 +++ persist/sqlite/query.go | 15 +++++++++++++++ 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/api/client.go b/api/client.go index 7e84bd29..e76ee7f5 100644 --- a/api/client.go +++ b/api/client.go @@ -67,8 +67,14 @@ func (c *Client) Tip() (resp types.ChainIndex, err error) { return } -// Block returns a block with the given block ID. +// Block returns the block with the specified ID. func (c *Client) Block(id types.BlockID) (resp types.Block, err error) { - err = c.c.GET(fmt.Sprintf("/explorer/block/%s", id), &resp) + err = c.c.GET(fmt.Sprintf("/explorer/block/id/%s", id), &resp) + return +} + +// BlockHeight returns the block with the specified height. +func (c *Client) BlockHeight(height uint64) (resp types.Block, err error) { + err = c.c.GET(fmt.Sprintf("/explorer/block/height/%d", height), &resp) return } diff --git a/api/server.go b/api/server.go index febaca75..6549338e 100644 --- a/api/server.go +++ b/api/server.go @@ -41,6 +41,7 @@ type ( Explorer interface { Tip() (types.ChainIndex, error) Block(id types.BlockID) (types.Block, error) + BlockHeight(height uint64) (types.Block, error) } ) @@ -151,6 +152,18 @@ func (s *server) explorerBlockHandler(jc jape.Context) { jc.Encode(block) } +func (s *server) explorerBlockHeightHandler(jc jape.Context) { + var height uint64 + if jc.DecodeParam("height", &height) != nil { + return + } + block, err := s.e.BlockHeight(height) + if jc.Check("failed to get block", err) != nil { + return + } + jc.Encode(block) +} + // NewServer returns an HTTP handler that serves the explored API. func NewServer(e Explorer, cm ChainManager, s Syncer) http.Handler { srv := server{ @@ -167,7 +180,8 @@ func NewServer(e Explorer, cm ChainManager, s Syncer) http.Handler { "GET /txpool/fee": srv.txpoolFeeHandler, "POST /txpool/broadcast": srv.txpoolBroadcastHandler, - "GET /explorer/tip": srv.explorerTipHandler, - "GET /explorer/block/:id": srv.explorerBlockHandler, + "GET /explorer/tip": srv.explorerTipHandler, + "GET /explorer/block/id/:id": srv.explorerBlockHandler, + "GET /explorer/block/height/:height": srv.explorerBlockHeightHandler, }) } diff --git a/explorer/explorer.go b/explorer/explorer.go index bf7cd592..f45b7b2b 100644 --- a/explorer/explorer.go +++ b/explorer/explorer.go @@ -12,6 +12,7 @@ type Store interface { Tip() (types.ChainIndex, error) Block(id types.BlockID) (types.Block, error) + BlockHeight(height uint64) (types.Block, error) } // Explorer implements a Sia explorer. @@ -33,3 +34,8 @@ func (e *Explorer) Tip() (types.ChainIndex, error) { func (e *Explorer) Block(id types.BlockID) (types.Block, error) { return e.s.Block(id) } + +// BlockHeight returns the block with the specified height. +func (e *Explorer) BlockHeight(height uint64) (types.Block, error) { + return e.s.BlockHeight(height) +} diff --git a/go.mod b/go.mod index e5829bdb..01cca0dc 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,8 @@ require ( github.com/mattn/go-sqlite3 v1.14.19 go.etcd.io/bbolt v1.3.7 go.sia.tech/core v0.1.12-0.20231021194448-f1e65eb9f0d0 - go.sia.tech/jape v0.9.0 + go.sia.tech/jape v0.11.1 + go.uber.org/zap v1.26.0 golang.org/x/term v0.6.0 lukechampine.com/frand v1.4.2 lukechampine.com/upnp v0.3.0 @@ -17,7 +18,6 @@ require ( github.com/julienschmidt/httprouter v1.3.0 // indirect go.sia.tech/mux v1.2.0 // indirect go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/tools v0.7.0 // indirect diff --git a/go.sum b/go.sum index d513a318..5ef5bcbb 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,11 @@ go.sia.tech/core v0.1.12-0.20231021194448-f1e65eb9f0d0 h1:2nKOKa99g9h9m3hL5UortA go.sia.tech/core v0.1.12-0.20231021194448-f1e65eb9f0d0/go.mod h1:3EoY+rR78w1/uGoXXVqcYdwSjSJKuEMI5bL7WROA27Q= go.sia.tech/jape v0.9.0 h1:kWgMFqALYhLMJYOwWBgJda5ko/fi4iZzRxHRP7pp8NY= go.sia.tech/jape v0.9.0/go.mod h1:4QqmBB+t3W7cNplXPj++ZqpoUb2PeiS66RLpXmEGap4= +go.sia.tech/jape v0.11.1 h1:M7IP+byXL7xOqzxcHUQuXW+q3sYMkYzmMlMw+q8ZZw0= +go.sia.tech/jape v0.11.1/go.mod h1:4QqmBB+t3W7cNplXPj++ZqpoUb2PeiS66RLpXmEGap4= go.sia.tech/mux v1.2.0 h1:ofa1Us9mdymBbGMY2XH/lSpY8itFsKIo/Aq8zwe+GHU= go.sia.tech/mux v1.2.0/go.mod h1:Yyo6wZelOYTyvrHmJZ6aQfRoer3o4xyKQ4NmQLJrBSo= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= diff --git a/persist/sqlite/query.go b/persist/sqlite/query.go index 8e5648d2..a94d25eb 100644 --- a/persist/sqlite/query.go +++ b/persist/sqlite/query.go @@ -73,3 +73,18 @@ func (s *Store) Block(id types.BlockID) (result types.Block, err error) { return } + +// BlockHeight implements explorer.Store. +func (s *Store) BlockHeight(height uint64) (result types.Block, err error) { + var data []byte + if err = s.queryRow("SELECT id FROM Blocks WHERE height = ?", height).Scan(&data); err != nil { + return + } + + var bid types.BlockID + if err = decode(&bid, data); err != nil { + return + } + result, err = s.Block(bid) + return +}