@@ -4,8 +4,10 @@ import (
44 "encoding/hex"
55 "fmt"
66 "math/big"
7+ "strconv"
78 "strings"
89 "sync"
10+ "time"
911
1012 "github.com/gin-gonic/gin"
1113 "github.com/rs/zerolog/log"
@@ -135,7 +137,7 @@ func executeSearch(storage storage.IMainStorage, chainId *big.Int, input SearchI
135137 return searchByAddress (storage , chainId , input .Address )
136138
137139 case input .FunctionSignature != "" :
138- transactions , err := searchByFunctionSelector (storage , chainId , input .FunctionSignature )
140+ transactions , err := searchByFunctionSelectorOptimistically (storage , chainId , input .FunctionSignature )
139141 return SearchResultModel {Transactions : transactions , Type : SearchResultTypeFunctionSignature }, err
140142
141143 default :
@@ -160,10 +162,16 @@ func searchByBlockNumber(mainStorage storage.IMainStorage, chainId *big.Int, blo
160162 return & block , nil
161163}
162164
163- func searchByFunctionSelector (mainStorage storage.IMainStorage , chainId * big.Int , functionSelector string ) ([]common.TransactionModel , error ) {
165+ func searchByFunctionSelectorOptimistically (mainStorage storage.IMainStorage , chainId * big.Int , functionSelector string ) ([]common.TransactionModel , error ) {
166+ now := time .Now ()
167+ thirtyDaysAgo := now .AddDate (0 , 0 , - 30 )
168+
164169 result , err := mainStorage .GetTransactions (storage.QueryFilter {
165170 ChainId : chainId ,
166171 Signature : functionSelector ,
172+ FilterParams : map [string ]string {
173+ "block_timestamp_gte" : strconv .FormatInt (thirtyDaysAgo .Unix (), 10 ),
174+ },
167175 SortBy : "block_number" ,
168176 SortOrder : "desc" ,
169177 Limit : 20 ,
@@ -172,7 +180,19 @@ func searchByFunctionSelector(mainStorage storage.IMainStorage, chainId *big.Int
172180 return nil , err
173181 }
174182 if len (result .Data ) == 0 {
175- return []common.TransactionModel {}, nil
183+ result , err = mainStorage .GetTransactions (storage.QueryFilter {
184+ ChainId : chainId ,
185+ Signature : functionSelector ,
186+ FilterParams : map [string ]string {
187+ "block_timestamp_lte" : strconv .FormatInt (thirtyDaysAgo .Unix (), 10 ),
188+ },
189+ SortBy : "block_number" ,
190+ SortOrder : "desc" ,
191+ Limit : 20 ,
192+ })
193+ if err != nil {
194+ return nil , err
195+ }
176196 }
177197
178198 transactions := make ([]common.TransactionModel , len (result .Data ))
@@ -189,25 +209,50 @@ func searchByHash(mainStorage storage.IMainStorage, chainId *big.Int, hash strin
189209 doneChan := make (chan struct {})
190210 errChan := make (chan error )
191211
192- // Try as transaction hash
193- wg . Add ( 1 )
212+ wg . Add ( 3 )
213+ // Try as transaction hash past 5 days
194214 go func () {
195215 defer wg .Done ()
196- txResult , err := mainStorage .GetTransactions (storage.QueryFilter {
197- ChainId : chainId ,
198- FilterParams : map [string ]string {
199- "hash" : hash ,
200- },
201- Limit : 1 ,
202- })
216+ txs , err := searchTransactionsByTimeRange (mainStorage , chainId , hash , 5 , 0 )
217+ if err != nil {
218+ errChan <- err
219+ return
220+ }
221+ if len (txs ) > 0 {
222+ select {
223+ case resultChan <- SearchResultModel {Transactions : []common.TransactionModel {txs [0 ]}, Type : SearchResultTypeTransaction }:
224+ case <- doneChan :
225+ }
226+ }
227+ }()
228+
229+ // Try as transaction hash past 5-30 days
230+ go func () {
231+ defer wg .Done ()
232+ txs , err := searchTransactionsByTimeRange (mainStorage , chainId , hash , 30 , 5 )
233+ if err != nil {
234+ errChan <- err
235+ return
236+ }
237+ if len (txs ) > 0 {
238+ select {
239+ case resultChan <- SearchResultModel {Transactions : []common.TransactionModel {txs [0 ]}, Type : SearchResultTypeTransaction }:
240+ case <- doneChan :
241+ }
242+ }
243+ }()
244+
245+ // Try as transaction hash more than 30 days ago
246+ go func () {
247+ defer wg .Done ()
248+ txs , err := searchTransactionsByTimeRange (mainStorage , chainId , hash , 0 , 30 )
203249 if err != nil {
204250 errChan <- err
205251 return
206252 }
207- if len (txResult .Data ) > 0 {
208- txModel := txResult .Data [0 ].Serialize ()
253+ if len (txs ) > 0 {
209254 select {
210- case resultChan <- SearchResultModel {Transactions : []common.TransactionModel {txModel }, Type : SearchResultTypeTransaction }:
255+ case resultChan <- SearchResultModel {Transactions : []common.TransactionModel {txs [ 0 ] }, Type : SearchResultTypeTransaction }:
211256 case <- doneChan :
212257 }
213258 }
@@ -299,7 +344,7 @@ func searchByAddress(mainStorage storage.IMainStorage, chainId *big.Int, address
299344 }
300345 return searchResult , err
301346 } else if contractCode == ContractCodeDoesNotExist {
302- txs , err := findLatestTransactionsFromAddress (mainStorage , chainId , address )
347+ txs , err := findLatestTransactionsFromAddressOptimistically (mainStorage , chainId , address )
303348 if err == nil {
304349 searchResult .Transactions = txs
305350 return searchResult , nil
@@ -318,7 +363,7 @@ func searchByAddress(mainStorage storage.IMainStorage, chainId *big.Int, address
318363 return searchResult , nil
319364 }
320365 }
321- transactionsFrom , err := findLatestTransactionsFromAddress (mainStorage , chainId , address )
366+ transactionsFrom , err := findLatestTransactionsFromAddressOptimistically (mainStorage , chainId , address )
322367 if err != nil {
323368 return searchResult , err
324369 }
@@ -345,17 +390,38 @@ func findLatestTransactionsToAddress(mainStorage storage.IMainStorage, chainId *
345390 return transactions , nil
346391}
347392
348- func findLatestTransactionsFromAddress (mainStorage storage.IMainStorage , chainId * big.Int , address string ) ([]common.TransactionModel , error ) {
393+ func findLatestTransactionsFromAddressOptimistically (mainStorage storage.IMainStorage , chainId * big.Int , address string ) ([]common.TransactionModel , error ) {
394+ now := time .Now ()
395+ thirtyDaysAgo := now .AddDate (0 , 0 , - 30 )
396+
349397 result , err := mainStorage .GetTransactions (storage.QueryFilter {
350398 ChainId : chainId ,
351399 FromAddress : address ,
352- Limit : 20 ,
353- SortBy : "block_number" ,
354- SortOrder : "desc" ,
400+ FilterParams : map [string ]string {
401+ "block_timestamp_gte" : strconv .FormatInt (thirtyDaysAgo .Unix (), 10 ),
402+ },
403+ Limit : 20 ,
404+ SortBy : "block_number" ,
405+ SortOrder : "desc" ,
355406 })
356407 if err != nil {
357408 return nil , err
358409 }
410+ if len (result .Data ) == 0 {
411+ result , err = mainStorage .GetTransactions (storage.QueryFilter {
412+ ChainId : chainId ,
413+ FromAddress : address ,
414+ FilterParams : map [string ]string {
415+ "block_timestamp_lte" : strconv .FormatInt (thirtyDaysAgo .Unix (), 10 ),
416+ },
417+ Limit : 20 ,
418+ SortBy : "block_number" ,
419+ SortOrder : "desc" ,
420+ })
421+ if err != nil {
422+ return nil , err
423+ }
424+ }
359425 transactions := make ([]common.TransactionModel , len (result .Data ))
360426 for i , transaction := range result .Data {
361427 transactions [i ] = transaction .Serialize ()
@@ -389,3 +455,32 @@ func checkIfContractHasCode(chainId *big.Int, address string) (ContractCodeState
389455 }
390456 return ContractCodeUnknown , nil
391457}
458+
459+ func searchTransactionsByTimeRange (mainStorage storage.IMainStorage , chainId * big.Int , hash string , startOffsetDays , endOffsetDays int ) ([]common.TransactionModel , error ) {
460+ now := time .Now ()
461+ filters := map [string ]string {
462+ "hash" : hash ,
463+ }
464+ if startOffsetDays > 0 {
465+ startTime := now .AddDate (0 , 0 , - startOffsetDays )
466+ filters ["block_timestamp_gte" ] = strconv .FormatInt (startTime .Unix (), 10 )
467+ }
468+ if endOffsetDays > 0 {
469+ endTime := now .AddDate (0 , 0 , - endOffsetDays )
470+ filters ["block_timestamp_lte" ] = strconv .FormatInt (endTime .Unix (), 10 )
471+ }
472+
473+ txResult , err := mainStorage .GetTransactions (storage.QueryFilter {
474+ ChainId : chainId ,
475+ FilterParams : filters ,
476+ Limit : 1 ,
477+ })
478+ if err != nil {
479+ return nil , err
480+ }
481+ serialized := make ([]common.TransactionModel , len (txResult .Data ))
482+ for i , tx := range txResult .Data {
483+ serialized [i ] = tx .Serialize ()
484+ }
485+ return serialized , nil
486+ }
0 commit comments