Skip to content

Commit

Permalink
Feature: search asset by name (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
aopoltorzhicky authored Oct 5, 2024
1 parent bffc3a3 commit 12fd4e3
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 8 deletions.
12 changes: 6 additions & 6 deletions cmd/api/handler/responses/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import "github.com/celenium-io/astria-indexer/internal/storage"
//
// @Description bridge account information
type Bridge struct {
Address string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"address" swaggertype:"string"`
Rollup []byte `example:"O0Ia+lPYYMf3iFfxBaWXCSdlhphc6d4ZoBXINov6Tjc=" json:"rollup" swaggertype:"string"`
Sudo string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"sudo" swaggertype:"string"`
Withdrawer string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"withdrawer" swaggertype:"string"`
Asset string `example:"nria" json:"asset" swaggertype:"string"`
FeeAsset string `example:"nria" json:"fee_asset" swaggertype:"string"`
Address string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"address" swaggertype:"string"`
Rollup []byte `example:"O0Ia+lPYYMf3iFfxBaWXCSdlhphc6d4ZoBXINov6Tjc=" json:"rollup" swaggertype:"string"`
Sudo string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"sudo,omitempty" swaggertype:"string"`
Withdrawer string `example:"astria1phym4uktjn6gjle226009ge7u82w0dgtszs8x2" json:"withdrawer,omitempty" swaggertype:"string"`
Asset string `example:"nria" json:"asset" swaggertype:"string"`
FeeAsset string `example:"nria" json:"fee_asset" swaggertype:"string"`
}

func NewBridge(b storage.Bridge) Bridge {
Expand Down
9 changes: 9 additions & 0 deletions cmd/api/handler/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type SearchHandler struct {
blocks storage.IBlock
txs storage.ITx
rollups storage.IRollup
bridges storage.IBridge
validators storage.IValidator
}

Expand All @@ -24,6 +25,7 @@ func NewSearchHandler(
blocks storage.IBlock,
txs storage.ITx,
rollups storage.IRollup,
bridges storage.IBridge,
validators storage.IValidator,
) *SearchHandler {
return &SearchHandler{
Expand All @@ -32,6 +34,7 @@ func NewSearchHandler(
blocks: blocks,
txs: txs,
rollups: rollups,
bridges: bridges,
validators: validators,
}
}
Expand Down Expand Up @@ -97,6 +100,12 @@ func (s *SearchHandler) Search(c echo.Context) error {
return handleError(c, err, s.address)
}
body = responses.NewShortValidator(validator)
case "bridge":
bridge, err := s.bridges.ById(c.Request().Context(), results[i].Id)
if err != nil {
return handleError(c, err, s.address)
}
body = responses.NewBridge(bridge)
}

response[i] = responses.NewSearchResult(results[i].Value, results[i].Type, body)
Expand Down
52 changes: 51 additions & 1 deletion cmd/api/handler/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type SearchTestSuite struct {
address *mock.MockIAddress
rollups *mock.MockIRollup
validators *mock.MockIValidator
bridges *mock.MockIBridge
echo *echo.Echo
handler *SearchHandler
ctrl *gomock.Controller
Expand All @@ -44,7 +45,8 @@ func (s *SearchTestSuite) SetupSuite() {
s.blocks = mock.NewMockIBlock(s.ctrl)
s.rollups = mock.NewMockIRollup(s.ctrl)
s.validators = mock.NewMockIValidator(s.ctrl)
s.handler = NewSearchHandler(s.search, s.address, s.blocks, s.txs, s.rollups, s.validators)
s.bridges = mock.NewMockIBridge(s.ctrl)
s.handler = NewSearchHandler(s.search, s.address, s.blocks, s.txs, s.rollups, s.bridges, s.validators)
}

// TearDownSuite -
Expand Down Expand Up @@ -251,3 +253,51 @@ func (s *SearchTestSuite) TestSearchValidator() {
s.Require().Equal("name", result.Value)
s.Require().NotNil(result.Body)
}

func (s *SearchTestSuite) TestSearchBridge() {
q := make(url.Values)
q.Add("query", "nam")

req := httptest.NewRequest(http.MethodGet, "/?"+q.Encode(), nil)
rec := httptest.NewRecorder()
c := s.echo.NewContext(req, rec)
c.SetPath("/search")

s.search.EXPECT().
Search(gomock.Any(), "nam").
Return([]storage.SearchResult{
{
Type: "bridge",
Value: "name",
Id: 1,
},
}, nil).
Times(1)

s.bridges.EXPECT().
ById(gomock.Any(), uint64(1)).
Return(storage.Bridge{
Id: 1,
Asset: "name",
Address: &testAddress,
AddressId: testAddress.Id,
Rollup: &testRollup,
RollupId: testRollup.Id,
FeeAsset: "fee_asset",
InitHeight: 1000,
}, nil).
Times(1)

s.Require().NoError(s.handler.Search(c))
s.Require().Equal(http.StatusOK, rec.Code)

var results []responses.SearchResult
err := json.NewDecoder(rec.Body).Decode(&results)
s.Require().NoError(err)
s.Require().Len(results, 1)

result := results[0]
s.Require().Equal("bridge", result.Type)
s.Require().Equal("name", result.Value)
s.Require().NotNil(result.Body)
}
2 changes: 1 addition & 1 deletion cmd/api/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func initHandlers(ctx context.Context, e *echo.Echo, cfg Config, db postgres.Sto
v1.GET("/constants", constantsHandler.Get)
v1.GET("/enums", constantsHandler.Enums)

searchHandler := handler.NewSearchHandler(db.Search, db.Address, db.Blocks, db.Tx, db.Rollup, db.Validator)
searchHandler := handler.NewSearchHandler(db.Search, db.Address, db.Blocks, db.Tx, db.Rollup, db.Bridges, db.Validator)
v1.GET("/search", searchHandler.Search)

addressHandlers := handler.NewAddressHandler(db.Address, db.Tx, db.Action, db.Rollup, db.Fee, db.Bridges, db.State, cfg.Indexer.Name)
Expand Down
1 change: 1 addition & 0 deletions internal/storage/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type IBridge interface {
ByRollup(ctx context.Context, rollupId uint64, limit, offset int) ([]Bridge, error)
ByRoles(ctx context.Context, addressId uint64, limit, offset int) ([]Bridge, error)
ListWithAddress(ctx context.Context, limit, offset int) ([]Bridge, error)
ById(ctx context.Context, id uint64) (Bridge, error)
}

type Bridge struct {
Expand Down
39 changes: 39 additions & 0 deletions internal/storage/mock/bridge.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions internal/storage/postgres/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,20 @@ func (b *Bridge) ListWithAddress(ctx context.Context, limit, offset int) (result
Scan(ctx, &result)
return
}

func (b *Bridge) ById(ctx context.Context, id uint64) (bridge storage.Bridge, err error) {
query := b.DB().NewSelect().
Model((*storage.Bridge)(nil)).
Where("id = ?", id)

err = b.DB().NewSelect().
TableExpr("(?) as bridge", query).
ColumnExpr("bridge.*").
ColumnExpr("address.hash as address__hash").
ColumnExpr("rollup.astria_id as rollup__astria_id").
Join("left join address as address on address.id = bridge.address_id").
Join("left join rollup on rollup.id = bridge.rollup_id").
Scan(ctx, &bridge)

return
}
26 changes: 26 additions & 0 deletions internal/storage/postgres/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,29 @@ func (s *StorageTestSuite) TestBridgeListWithAddress() {
s.Require().Nil(bridge.Withdrawer)
s.Require().Nil(bridge.Rollup)
}

func (s *StorageTestSuite) TestBridgeById() {
ctx, ctxCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer ctxCancel()

bridge, err := s.storage.Bridges.ById(ctx, 1)
s.Require().NoError(err)

s.Require().EqualValues(7316, bridge.InitHeight)
s.Require().EqualValues(1, bridge.AddressId)
s.Require().EqualValues(1, bridge.SudoId)
s.Require().EqualValues(1, bridge.WithdrawerId)
s.Require().EqualValues(1, bridge.RollupId)
s.Require().EqualValues("nria", bridge.Asset)
s.Require().EqualValues("nria", bridge.FeeAsset)

s.Require().NotNil(bridge.Address)
s.Require().Equal("astria1lm45urgugesyhaymn68xww0m6g49zreqa32w7p", bridge.Address.Hash)

s.Require().Nil(bridge.Sudo)
s.Require().Nil(bridge.Withdrawer)

s.Require().NotNil(bridge.Rollup)
hash, _ := hex.DecodeString("19ba8abb3e4b56a309df6756c47b97e298e3a72d88449d36a0fadb1ca7366539")
s.Require().Equal(hash, bridge.Rollup.AstriaId)
}
9 changes: 9 additions & 0 deletions internal/storage/postgres/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,15 @@ func createIndices(ctx context.Context, conn *database.Bun) error {
Exec(ctx); err != nil {
return err
}
if _, err := tx.NewCreateIndex().
IfNotExists().
Model((*storage.Bridge)(nil)).
Index("bridge_asset_idx").
ColumnExpr("asset gin_trgm_ops").
Using("GIN").
Exec(ctx); err != nil {
return err
}

// Fee
if _, err := tx.NewCreateIndex().
Expand Down
7 changes: 7 additions & 0 deletions internal/storage/postgres/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ func (s *Search) Search(ctx context.Context, query string) (results []storage.Se
ColumnExpr("id, name as value, 'validator' as type").
Where("name ILIKE ?", text)

bridgeQuery := s.db.DB().NewSelect().
Model((*storage.Bridge)(nil)).
ColumnExpr("id, asset as value, 'bridge' as type").
Where("asset ILIKE ?", text)

searchQuery = searchQuery.UnionAll(bridgeQuery)

if hash, err := hex.DecodeString(query); err == nil {
blockQuery := s.db.DB().NewSelect().
Model((*storage.Block)(nil)).
Expand Down
14 changes: 14 additions & 0 deletions internal/storage/postgres/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,17 @@ func (s *StorageTestSuite) TestSearchValidatorByAddress() {
s.Require().EqualValues("validator", result1.Type)
s.Require().EqualValues(1, result1.Id)
}

func (s *StorageTestSuite) TestSearchBridge() {
ctx, ctxCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer ctxCancel()

results, err := s.storage.Search.Search(ctx, "nri")
s.Require().NoError(err)
s.Require().Len(results, 1)

result := results[0]
s.Require().EqualValues("nria", result.Value)
s.Require().EqualValues("bridge", result.Type)
s.Require().EqualValues(1, result.Id)
}

0 comments on commit 12fd4e3

Please sign in to comment.