@@ -2,11 +2,15 @@ package dataaccess
22
33import (
44 "context"
5+ "database/sql"
6+ "fmt"
57 "strings"
68
9+ "github.com/doug-martin/goqu/v9"
710 "github.com/ethereum/go-ethereum/common/hexutil"
811 t "github.com/gobitfly/beaconchain/pkg/api/types"
912 "github.com/gobitfly/beaconchain/pkg/commons/db"
13+ "github.com/pkg/errors"
1014)
1115
1216type SearchRepository interface {
@@ -18,6 +22,11 @@ type SearchRepository interface {
1822 GetSearchValidatorsByWithdrawalEnsName (ctx context.Context , chainId uint64 , ensName string ) (* t.SearchValidatorsByWithdrawalCredential , error )
1923 GetSearchValidatorsByGraffiti (ctx context.Context , chainId uint64 , graffiti string ) (* t.SearchValidatorsByGraffiti , error )
2024 GetSearchValidatorsByGraffitiHex (ctx context.Context , chainId uint64 , graffiti []byte ) (* t.SearchValidatorsByGraffiti , error )
25+ GetSearchAddress (ctx context.Context , chainId uint64 , address []byte ) (* t.SearchAddress , error )
26+ GetSearchTransaction (ctx context.Context , chainId uint64 , transactionHash []byte ) (* t.SearchTransaction , error )
27+ GetSearchBlock (ctx context.Context , chainId uint64 , blockNumber uint64 ) (* t.SearchBlock , error )
28+ GetSearchEpoch (ctx context.Context , chainId uint64 , epoch uint64 ) (* t.SearchEpoch , error )
29+ GetSearchToken (ctx context.Context , chainId uint64 , address []byte ) (* t.SearchToken , error )
2130}
2231
2332func (d * DataAccessService ) GetSearchValidatorByIndex (ctx context.Context , chainId , index uint64 ) (* t.SearchValidator , error ) {
@@ -131,3 +140,90 @@ func (d *DataAccessService) GetSearchValidatorsByGraffitiHex(ctx context.Context
131140 }
132141 return ret , nil
133142}
143+
144+ func (d * DataAccessService ) GetSearchAddress (ctx context.Context , chainId uint64 , address []byte ) (* t.SearchAddress , error ) {
145+ eth1AddressSearchItem , err := d .bigtable .SearchForAddress (address , 1 )
146+ if err != nil {
147+ return nil , fmt .Errorf ("failed to search for address %s: %w" , hexutil .Encode (address ), err )
148+ }
149+ if len (eth1AddressSearchItem ) == 0 || eth1AddressSearchItem [0 ] == nil {
150+ return nil , ErrNotFound
151+ }
152+ foundAddress := * eth1AddressSearchItem [0 ]
153+ return & t.SearchAddress {
154+ Address : t.Address {
155+ Hash : t .Hash ("0x" + foundAddress .Address ),
156+ Label : foundAddress .Name ,
157+ IsContract : foundAddress .Token != "" ,
158+ },
159+ }, nil
160+ }
161+
162+ func (d * DataAccessService ) GetSearchTransaction (ctx context.Context , chainId uint64 , transactionHash []byte ) (* t.SearchTransaction , error ) {
163+ tx , err := db .BigtableClient .GetIndexedEth1Transaction (transactionHash )
164+ if err != nil {
165+ return nil , fmt .Errorf ("failed to search for transaction %s: %w" , hexutil .Encode (transactionHash ), err )
166+ }
167+ if tx == nil {
168+ return nil , ErrNotFound
169+ }
170+ return & t.SearchTransaction {
171+ TransactionHash : t .Hash (hexutil .Encode (tx .Hash )),
172+ }, nil
173+ }
174+
175+ func (d * DataAccessService ) GetSearchBlock (ctx context.Context , chainId uint64 , blockNumber uint64 ) (* t.SearchBlock , error ) {
176+ block , err := db .BigtableClient .GetBlockFromBlocksTable (blockNumber )
177+ if err != nil {
178+ if err == db .ErrBlockNotFound {
179+ return nil , ErrNotFound
180+ }
181+ return nil , fmt .Errorf ("failed to search for block %d: %w" , blockNumber , err )
182+ }
183+ if block == nil {
184+ return nil , fmt .Errorf ("nil block returned for block number %d" , blockNumber )
185+ }
186+ return & t.SearchBlock {
187+ BlockNumber : block .Number ,
188+ }, nil
189+ }
190+
191+ func (d * DataAccessService ) GetSearchEpoch (ctx context.Context , chainId uint64 , epoch uint64 ) (* t.SearchEpoch , error ) {
192+ ds := goqu .Dialect ("postgres" ).
193+ From ("epochs" ).
194+ Select (goqu .I ("epoch" )).
195+ Where (goqu .I ("epoch" ).Eq (epoch ))
196+
197+ foundEpoch , err := runQuery [uint64 ](ctx , d .readerDb , ds )
198+ if err != nil {
199+ if errors .Is (err , sql .ErrNoRows ) {
200+ return nil , ErrNotFound
201+ }
202+ return nil , err
203+ }
204+ return & t.SearchEpoch {
205+ Epoch : foundEpoch ,
206+ }, nil
207+ }
208+
209+ func (d * DataAccessService ) GetSearchToken (ctx context.Context , chainId uint64 , address []byte ) (* t.SearchToken , error ) {
210+ eth1AddressSearchItem , err := d .bigtable .SearchForAddress (address , 1 )
211+ if err != nil {
212+ return nil , fmt .Errorf ("failed to search for address %s: %w" , hexutil .Encode (address ), err )
213+ }
214+ if len (eth1AddressSearchItem ) == 0 || eth1AddressSearchItem [0 ] == nil {
215+ return nil , ErrNotFound
216+ }
217+ foundAddress := * eth1AddressSearchItem [0 ]
218+ if foundAddress .Token == "" {
219+ return nil , ErrNotFound
220+ }
221+ return & t.SearchToken {
222+ Address : t.Address {
223+ Hash : t .Hash ("0x" + foundAddress .Address ),
224+ IsContract : true ,
225+ Label : foundAddress .Name ,
226+ },
227+ Token : foundAddress .Token ,
228+ }, nil
229+ }
0 commit comments