Skip to content

Commit 8a8a551

Browse files
committed
try to search optimistically from newer data
1 parent 0d06d2f commit 8a8a551

File tree

1 file changed

+116
-21
lines changed

1 file changed

+116
-21
lines changed

internal/handlers/search_handlers.go

Lines changed: 116 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)