121 lines
4.1 KiB
Go
121 lines
4.1 KiB
Go
package indexer
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/elastic/go-elasticsearch/v8"
|
|
"github.com/elastic/go-elasticsearch/v8/esapi"
|
|
)
|
|
|
|
// SearchIndexer handles indexing documents to Elasticsearch/OpenSearch
|
|
type SearchIndexer struct {
|
|
client *elasticsearch.Client
|
|
indexPrefix string
|
|
}
|
|
|
|
// NewSearchIndexer creates a new search indexer
|
|
func NewSearchIndexer(client *elasticsearch.Client, indexPrefix string) *SearchIndexer {
|
|
return &SearchIndexer{
|
|
client: client,
|
|
indexPrefix: indexPrefix,
|
|
}
|
|
}
|
|
|
|
// IndexBlock indexes a block document
|
|
func (s *SearchIndexer) IndexBlock(ctx context.Context, chainID int, block *BlockDocument) error {
|
|
indexName := fmt.Sprintf("%s-blocks-%d", s.indexPrefix, chainID)
|
|
return s.indexDocument(ctx, indexName, block.Hash, block)
|
|
}
|
|
|
|
// IndexTransaction indexes a transaction document
|
|
func (s *SearchIndexer) IndexTransaction(ctx context.Context, chainID int, tx *TransactionDocument) error {
|
|
indexName := fmt.Sprintf("%s-transactions-%d", s.indexPrefix, chainID)
|
|
return s.indexDocument(ctx, indexName, tx.Hash, tx)
|
|
}
|
|
|
|
// IndexAddress indexes an address document
|
|
func (s *SearchIndexer) IndexAddress(ctx context.Context, chainID int, addr *AddressDocument) error {
|
|
indexName := fmt.Sprintf("%s-addresses-%d", s.indexPrefix, chainID)
|
|
return s.indexDocument(ctx, indexName, addr.Address, addr)
|
|
}
|
|
|
|
// indexDocument indexes a document to Elasticsearch
|
|
func (s *SearchIndexer) indexDocument(ctx context.Context, indexName, docID string, doc interface{}) error {
|
|
body, err := json.Marshal(doc)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal document: %w", err)
|
|
}
|
|
|
|
req := esapi.IndexRequest{
|
|
Index: indexName,
|
|
DocumentID: docID,
|
|
Body: bytes.NewReader(body),
|
|
Refresh: "false",
|
|
}
|
|
|
|
res, err := req.Do(ctx, s.client)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to index document: %w", err)
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
if res.IsError() {
|
|
return fmt.Errorf("elasticsearch error: %s", res.String())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// BlockDocument represents a block in the search index
|
|
type BlockDocument struct {
|
|
BlockNumber int64 `json:"block_number"`
|
|
Hash string `json:"hash"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Miner string `json:"miner"`
|
|
TransactionCount int `json:"transaction_count"`
|
|
GasUsed int64 `json:"gas_used"`
|
|
GasLimit int64 `json:"gas_limit"`
|
|
ChainID int `json:"chain_id"`
|
|
ParentHash string `json:"parent_hash"`
|
|
Size int64 `json:"size"`
|
|
}
|
|
|
|
// TransactionDocument represents a transaction in the search index
|
|
type TransactionDocument struct {
|
|
Hash string `json:"hash"`
|
|
BlockNumber int64 `json:"block_number"`
|
|
TransactionIndex int `json:"transaction_index"`
|
|
FromAddress string `json:"from_address"`
|
|
ToAddress string `json:"to_address"`
|
|
Value string `json:"value"`
|
|
ValueNumeric int64 `json:"value_numeric"`
|
|
GasPrice int64 `json:"gas_price"`
|
|
GasUsed int64 `json:"gas_used"`
|
|
Status string `json:"status"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
ChainID int `json:"chain_id"`
|
|
InputDataLength int `json:"input_data_length"`
|
|
IsContractCreation bool `json:"is_contract_creation"`
|
|
ContractAddress string `json:"contract_address,omitempty"`
|
|
}
|
|
|
|
// AddressDocument represents an address in the search index
|
|
type AddressDocument struct {
|
|
Address string `json:"address"`
|
|
ChainID int `json:"chain_id"`
|
|
Label string `json:"label,omitempty"`
|
|
Tags []string `json:"tags,omitempty"`
|
|
TokenCount int `json:"token_count"`
|
|
TransactionCount int64 `json:"transaction_count"`
|
|
FirstSeen time.Time `json:"first_seen"`
|
|
LastSeen time.Time `json:"last_seen"`
|
|
IsContract bool `json:"is_contract"`
|
|
ContractName string `json:"contract_name,omitempty"`
|
|
BalanceETH string `json:"balance_eth"`
|
|
BalanceUSD float64 `json:"balance_usd,omitempty"`
|
|
}
|