From eae458f44c68d8aa0ca6f291787f7ada5abf33cc Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 11 Sep 2024 17:57:16 +0300 Subject: [PATCH 1/3] Add chains and deploys. --- blockchain/b3/b3.go | 845 ++++++++++++++++ blockchain/b3/b3_index_types.pb.go | 912 +++++++++++++++++ blockchain/b3/b3_index_types.proto | 78 ++ blockchain/b3_sepolia/b3_sepolia.go | 845 ++++++++++++++++ .../b3_sepolia/b3_sepolia_index_types.pb.go | 917 ++++++++++++++++++ .../b3_sepolia/b3_sepolia_index_types.proto | 78 ++ blockchain/handlers.go | 6 + crawler/settings.go | 12 + deploy/deploy.bash | 37 +- deploy/monitoring-seer-crawlers.service | 2 +- deploy/seer-crawler-b3-sepolia.service | 0 deploy/seer-crawler-b3.service | 0 deploy/seer-synchronizer-b3-sepolia.service | 0 deploy/seer-synchronizer-b3.service | 0 indexer/db.go | 4 + prepare_blockchains.sh | 2 +- sample.env | 2 + 17 files changed, 3737 insertions(+), 3 deletions(-) create mode 100644 blockchain/b3/b3.go create mode 100644 blockchain/b3/b3_index_types.pb.go create mode 100644 blockchain/b3/b3_index_types.proto create mode 100644 blockchain/b3_sepolia/b3_sepolia.go create mode 100644 blockchain/b3_sepolia/b3_sepolia_index_types.pb.go create mode 100644 blockchain/b3_sepolia/b3_sepolia_index_types.proto create mode 100644 deploy/seer-crawler-b3-sepolia.service create mode 100644 deploy/seer-crawler-b3.service create mode 100644 deploy/seer-synchronizer-b3-sepolia.service create mode 100644 deploy/seer-synchronizer-b3.service diff --git a/blockchain/b3/b3.go b/blockchain/b3/b3.go new file mode 100644 index 0000000..f2a9390 --- /dev/null +++ b/blockchain/b3/b3.go @@ -0,0 +1,845 @@ +package b3 + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "log" + "math/big" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "google.golang.org/protobuf/proto" + + seer_common "github.com/moonstream-to/seer/blockchain/common" + "github.com/moonstream-to/seer/indexer" + "github.com/moonstream-to/seer/version" +) + +func NewClient(url string, timeout int) (*Client, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + rpcClient, err := rpc.DialContext(ctx, url) + if err != nil { + return nil, err + } + return &Client{rpcClient: rpcClient}, nil +} + +// Client is a wrapper around the Ethereum JSON-RPC client. + +type Client struct { + rpcClient *rpc.Client +} + +// Client common + +// ChainType returns the chain type. +func (c *Client) ChainType() string { + return "b3" +} + +// Close closes the underlying RPC client. +func (c *Client) Close() { + c.rpcClient.Close() +} + +// GetLatestBlockNumber returns the latest block number. +func (c *Client) GetLatestBlockNumber() (*big.Int, error) { + var result string + if err := c.rpcClient.CallContext(context.Background(), &result, "eth_blockNumber"); err != nil { + return nil, err + } + + // Convert the hex string to a big.Int + blockNumber, ok := new(big.Int).SetString(result, 0) // The 0 base lets the function infer the base from the string prefix. + if !ok { + return nil, fmt.Errorf("invalid block number format: %s", result) + } + + return blockNumber, nil +} + +// BlockByNumber returns the block with the given number. +func (c *Client) GetBlockByNumber(ctx context.Context, number *big.Int) (*seer_common.BlockJson, error) { + + var rawResponse json.RawMessage // Use RawMessage to capture the entire JSON response + err := c.rpcClient.CallContext(ctx, &rawResponse, "eth_getBlockByNumber", "0x"+number.Text(16), true) + if err != nil { + fmt.Println("Error calling eth_getBlockByNumber: ", err) + return nil, err + } + + var response_json map[string]interface{} + + err = json.Unmarshal(rawResponse, &response_json) + + delete(response_json, "transactions") + + var block *seer_common.BlockJson + err = c.rpcClient.CallContext(ctx, &block, "eth_getBlockByNumber", "0x"+number.Text(16), true) // true to include transactions + return block, err +} + +// BlockByHash returns the block with the given hash. +func (c *Client) BlockByHash(ctx context.Context, hash common.Hash) (*seer_common.BlockJson, error) { + var block *seer_common.BlockJson + err := c.rpcClient.CallContext(ctx, &block, "eth_getBlockByHash", hash, true) // true to include transactions + return block, err +} + +// TransactionReceipt returns the receipt of a transaction by transaction hash. +func (c *Client) TransactionReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) { + var receipt *types.Receipt + err := c.rpcClient.CallContext(ctx, &receipt, "eth_getTransactionReceipt", hash) + return receipt, err +} + +func (c *Client) ClientFilterLogs(ctx context.Context, q ethereum.FilterQuery, debug bool) ([]*seer_common.EventJson, error) { + var logs []*seer_common.EventJson + fromBlock := q.FromBlock + toBlock := q.ToBlock + batchStep := new(big.Int).Sub(toBlock, fromBlock) // Calculate initial batch step + + for { + // Calculate the next "lastBlock" within the batch step or adjust to "toBlock" if exceeding + nextBlock := new(big.Int).Add(fromBlock, batchStep) + if nextBlock.Cmp(toBlock) > 0 { + nextBlock = new(big.Int).Set(toBlock) + } + + var result []*seer_common.EventJson + err := c.rpcClient.CallContext(ctx, &result, "eth_getLogs", struct { + FromBlock string `json:"fromBlock"` + ToBlock string `json:"toBlock"` + Addresses []common.Address `json:"addresses"` + Topics [][]common.Hash `json:"topics"` + }{ + FromBlock: toHex(fromBlock), + ToBlock: toHex(nextBlock), + Addresses: q.Addresses, + Topics: q.Topics, + }) + + if err != nil { + if strings.Contains(err.Error(), "query returned more than 10000 results") { + // Halve the batch step if too many results and retry + batchStep.Div(batchStep, big.NewInt(2)) + if batchStep.Cmp(big.NewInt(1)) < 0 { + // If the batch step is too small we will skip that block + fromBlock = new(big.Int).Add(nextBlock, big.NewInt(1)) + if fromBlock.Cmp(toBlock) > 0 { + break + } + continue + } + continue + } else { + // For any other error, return immediately + return nil, err + } + } + + // Append the results and adjust "fromBlock" for the next batch + logs = append(logs, result...) + fromBlock = new(big.Int).Add(nextBlock, big.NewInt(1)) + + if debug { + log.Printf("Fetched logs: %d", len(result)) + } + + // Break the loop if we've reached or exceeded "toBlock" + if fromBlock.Cmp(toBlock) > 0 { + break + } + } + + return logs, nil +} + +// Utility function to convert big.Int to its hexadecimal representation. +func toHex(number *big.Int) string { + return fmt.Sprintf("0x%x", number) +} + +func fromHex(hex string) *big.Int { + number := new(big.Int) + number.SetString(hex, 0) + return number +} + +// FetchBlocksInRange fetches blocks within a specified range. +// This could be useful for batch processing or analysis. +func (c *Client) FetchBlocksInRange(from, to *big.Int, debug bool) ([]*seer_common.BlockJson, error) { + var blocks []*seer_common.BlockJson + ctx := context.Background() // For simplicity, using a background context; consider timeouts for production. + + for i := new(big.Int).Set(from); i.Cmp(to) <= 0; i.Add(i, big.NewInt(1)) { + block, err := c.GetBlockByNumber(ctx, i) + if err != nil { + return nil, err + } + + blocks = append(blocks, block) + if debug { + log.Printf("Fetched block number: %d", i) + } + } + + return blocks, nil +} + +// FetchBlocksInRangeAsync fetches blocks within a specified range concurrently. +func (c *Client) FetchBlocksInRangeAsync(from, to *big.Int, debug bool, maxRequests int) ([]*seer_common.BlockJson, error) { + var ( + blocks []*seer_common.BlockJson + + mu sync.Mutex + wg sync.WaitGroup + ctx = context.Background() + ) + + var blockNumbersRange []*big.Int + for i := new(big.Int).Set(from); i.Cmp(to) <= 0; i.Add(i, big.NewInt(1)) { + blockNumbersRange = append(blockNumbersRange, new(big.Int).Set(i)) + } + + sem := make(chan struct{}, maxRequests) // Semaphore to control concurrency + errChan := make(chan error, 1) + + for _, b := range blockNumbersRange { + wg.Add(1) + go func(b *big.Int) { + defer wg.Done() + + sem <- struct{}{} // Acquire semaphore + + block, getErr := c.GetBlockByNumber(ctx, b) + if getErr != nil { + log.Printf("Failed to fetch block number: %d, error: %v", b, getErr) + errChan <- getErr + return + } + + mu.Lock() + blocks = append(blocks, block) + mu.Unlock() + + if debug { + log.Printf("Fetched block number: %d", b) + } + + <-sem + }(b) + } + + wg.Wait() + close(sem) + close(errChan) + + if err := <-errChan; err != nil { + return nil, err + } + + return blocks, nil +} + +// ParseBlocksWithTransactions parses blocks and their transactions into custom data structure. +// This method showcases how to handle and transform detailed block and transaction data. +func (c *Client) ParseBlocksWithTransactions(from, to *big.Int, debug bool, maxRequests int) ([]*B3Block, error) { + var blocksWithTxsJson []*seer_common.BlockJson + var fetchErr error + if maxRequests > 1 { + blocksWithTxsJson, fetchErr = c.FetchBlocksInRangeAsync(from, to, debug, maxRequests) + } else { + blocksWithTxsJson, fetchErr = c.FetchBlocksInRange(from, to, debug) + } + if fetchErr != nil { + return nil, fetchErr + } + + var parsedBlocks []*B3Block + for _, blockAndTxsJson := range blocksWithTxsJson { + // Convert BlockJson to Block and Transactions as required. + parsedBlock := ToProtoSingleBlock(blockAndTxsJson) + + for _, txJson := range blockAndTxsJson.Transactions { + txJson.BlockTimestamp = blockAndTxsJson.Timestamp + + parsedTransaction := ToProtoSingleTransaction(&txJson) + parsedBlock.Transactions = append(parsedBlock.Transactions, parsedTransaction) + } + + parsedBlocks = append(parsedBlocks, parsedBlock) + } + + return parsedBlocks, nil +} + +func (c *Client) ParseEvents(from, to *big.Int, blocksCache map[uint64]indexer.BlockCache, debug bool) ([]*B3EventLog, error) { + logs, err := c.ClientFilterLogs(context.Background(), ethereum.FilterQuery{ + FromBlock: from, + ToBlock: to, + }, debug) + + if err != nil { + fmt.Println("Error fetching logs: ", err) + return nil, err + } + + var parsedEvents []*B3EventLog + + for _, log := range logs { + parsedEvent := ToProtoSingleEventLog(log) + parsedEvents = append(parsedEvents, parsedEvent) + + } + + return parsedEvents, nil +} + +func (c *Client) FetchAsProtoBlocksWithEvents(from, to *big.Int, debug bool, maxRequests int) ([]proto.Message, []indexer.BlockIndex, uint64, error) { + blocks, err := c.ParseBlocksWithTransactions(from, to, debug, maxRequests) + if err != nil { + return nil, nil, 0, err + } + + var blocksSize uint64 + + blocksCache := make(map[uint64]indexer.BlockCache) + + for _, block := range blocks { + blocksCache[block.BlockNumber] = indexer.BlockCache{ + BlockNumber: block.BlockNumber, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + } // Assuming block.BlockNumber is int64 and block.Hash is string + } + + events, err := c.ParseEvents(from, to, blocksCache, debug) + if err != nil { + return nil, nil, 0, err + } + + var blocksProto []proto.Message + var blocksIndex []indexer.BlockIndex + + for bI, block := range blocks { + for _, tx := range block.Transactions { + for _, event := range events { + if tx.Hash == event.TransactionHash { + tx.Logs = append(tx.Logs, event) + } + } + } + + + // Prepare blocks to index + blocksIndex = append(blocksIndex, indexer.NewBlockIndex("b3", + block.BlockNumber, + block.Hash, + block.Timestamp, + block.ParentHash, + uint64(bI), + "", + 0, + )) + + blocksSize += uint64(proto.Size(block)) + blocksProto = append(blocksProto, block) // Assuming block is already a proto.Message + } + + return blocksProto, blocksIndex, blocksSize, nil +} + +func (c *Client) ProcessBlocksToBatch(msgs []proto.Message) (proto.Message, error) { + var blocks []*B3Block + for _, msg := range msgs { + block, ok := msg.(*B3Block) + if !ok { + return nil, fmt.Errorf("failed to type assert proto.Message to *B3Block") + } + blocks = append(blocks, block) + } + + return &B3BlocksBatch{ + Blocks: blocks, + SeerVersion: version.SeerVersion, + }, nil +} + +func ToEntireBlocksBatchFromLogProto(obj *B3BlocksBatch) *seer_common.BlocksBatchJson { + blocksBatchJson := seer_common.BlocksBatchJson{ + Blocks: []seer_common.BlockJson{}, + SeerVersion: obj.SeerVersion, + } + + for _, b := range obj.Blocks { + var txs []seer_common.TransactionJson + for _, tx := range b.Transactions { + var accessList []seer_common.AccessList + for _, al := range tx.AccessList { + accessList = append(accessList, seer_common.AccessList{ + Address: al.Address, + StorageKeys: al.StorageKeys, + }) + } + var events []seer_common.EventJson + for _, e := range tx.Logs { + events = append(events, seer_common.EventJson{ + Address: e.Address, + Topics: e.Topics, + Data: e.Data, + BlockNumber: fmt.Sprintf("%d", e.BlockNumber), + TransactionHash: e.TransactionHash, + BlockHash: e.BlockHash, + Removed: e.Removed, + LogIndex: fmt.Sprintf("%d", e.LogIndex), + TransactionIndex: fmt.Sprintf("%d", e.TransactionIndex), + }) + } + txs = append(txs, seer_common.TransactionJson{ + BlockHash: tx.BlockHash, + BlockNumber: fmt.Sprintf("%d", tx.BlockNumber), + ChainId: tx.ChainId, + FromAddress: tx.FromAddress, + Gas: tx.Gas, + GasPrice: tx.GasPrice, + Hash: tx.Hash, + Input: tx.Input, + MaxFeePerGas: tx.MaxFeePerGas, + MaxPriorityFeePerGas: tx.MaxPriorityFeePerGas, + Nonce: tx.Nonce, + V: tx.V, + R: tx.R, + S: tx.S, + ToAddress: tx.ToAddress, + TransactionIndex: fmt.Sprintf("%d", tx.TransactionIndex), + TransactionType: fmt.Sprintf("%d", tx.TransactionType), + Value: tx.Value, + IndexedAt: fmt.Sprintf("%d", tx.IndexedAt), + BlockTimestamp: fmt.Sprintf("%d", tx.BlockTimestamp), + AccessList: accessList, + YParity: tx.YParity, + + Events: events, + }) + } + + blocksBatchJson.Blocks = append(blocksBatchJson.Blocks, seer_common.BlockJson{ + Difficulty: fmt.Sprintf("%d", b.Difficulty), + ExtraData: b.ExtraData, + GasLimit: fmt.Sprintf("%d", b.GasLimit), + GasUsed: fmt.Sprintf("%d", b.GasUsed), + Hash: b.Hash, + LogsBloom: b.LogsBloom, + Miner: b.Miner, + Nonce: b.Nonce, + BlockNumber: fmt.Sprintf("%d", b.BlockNumber), + ParentHash: b.ParentHash, + ReceiptsRoot: b.ReceiptsRoot, + Sha3Uncles: b.Sha3Uncles, + StateRoot: b.StateRoot, + Timestamp: fmt.Sprintf("%d", b.Timestamp), + TotalDifficulty: b.TotalDifficulty, + TransactionsRoot: b.TransactionsRoot, + Size: fmt.Sprintf("%d", b.Size), + BaseFeePerGas: b.BaseFeePerGas, + IndexedAt: fmt.Sprintf("%d", b.IndexedAt), + + + + + + + Transactions: txs, + }) + } + + return &blocksBatchJson +} + +func ToProtoSingleBlock(obj *seer_common.BlockJson) *B3Block { + return &B3Block{ + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + Difficulty: fromHex(obj.Difficulty).Uint64(), + ExtraData: obj.ExtraData, + GasLimit: fromHex(obj.GasLimit).Uint64(), + GasUsed: fromHex(obj.GasUsed).Uint64(), + BaseFeePerGas: obj.BaseFeePerGas, + Hash: obj.Hash, + LogsBloom: obj.LogsBloom, + Miner: obj.Miner, + Nonce: obj.Nonce, + ParentHash: obj.ParentHash, + ReceiptsRoot: obj.ReceiptsRoot, + Sha3Uncles: obj.Sha3Uncles, + Size: fromHex(obj.Size).Uint64(), + StateRoot: obj.StateRoot, + Timestamp: fromHex(obj.Timestamp).Uint64(), + TotalDifficulty: obj.TotalDifficulty, + TransactionsRoot: obj.TransactionsRoot, + IndexedAt: fromHex(obj.IndexedAt).Uint64(), + + + + + + } +} + +func ToProtoSingleTransaction(obj *seer_common.TransactionJson) *B3Transaction { + var accessList []*B3TransactionAccessList + for _, al := range obj.AccessList { + accessList = append(accessList, &B3TransactionAccessList{ + Address: al.Address, + StorageKeys: al.StorageKeys, + }) + } + + return &B3Transaction{ + Hash: obj.Hash, + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + BlockHash: obj.BlockHash, + FromAddress: obj.FromAddress, + ToAddress: obj.ToAddress, + Gas: obj.Gas, + GasPrice: obj.GasPrice, + MaxFeePerGas: obj.MaxFeePerGas, + MaxPriorityFeePerGas: obj.MaxPriorityFeePerGas, + Input: obj.Input, + Nonce: obj.Nonce, + TransactionIndex: fromHex(obj.TransactionIndex).Uint64(), + TransactionType: fromHex(obj.TransactionType).Uint64(), + Value: obj.Value, + IndexedAt: fromHex(obj.IndexedAt).Uint64(), + BlockTimestamp: fromHex(obj.BlockTimestamp).Uint64(), + + ChainId: obj.ChainId, + V: obj.V, + R: obj.R, + S: obj.S, + + AccessList: accessList, + YParity: obj.YParity, + } +} + +func ToEvenFromLogProto(obj *B3EventLog) *seer_common.EventJson { + return &seer_common.EventJson{ + Address: obj.Address, + Topics: obj.Topics, + Data: obj.Data, + BlockNumber: fmt.Sprintf("%d", obj.BlockNumber), + TransactionHash: obj.TransactionHash, + LogIndex: fmt.Sprintf("%d", obj.LogIndex), + BlockHash: obj.BlockHash, + Removed: obj.Removed, + } +} + +func ToProtoSingleEventLog(obj *seer_common.EventJson) *B3EventLog { + return &B3EventLog{ + Address: obj.Address, + Topics: obj.Topics, + Data: obj.Data, + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + TransactionHash: obj.TransactionHash, + LogIndex: fromHex(obj.LogIndex).Uint64(), + BlockHash: obj.BlockHash, + Removed: obj.Removed, + } +} + +func (c *Client) DecodeProtoEventLogs(data []string) ([]*B3EventLog, error) { + var events []*B3EventLog + for _, d := range data { + var event B3EventLog + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &event); err != nil { + return nil, err + } + events = append(events, &event) + } + return events, nil +} + +func (c *Client) DecodeProtoTransactions(data []string) ([]*B3Transaction, error) { + var transactions []*B3Transaction + for _, d := range data { + var transaction B3Transaction + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &transaction); err != nil { + return nil, err + } + transactions = append(transactions, &transaction) + } + return transactions, nil +} + +func (c *Client) DecodeProtoBlocks(data []string) ([]*B3Block, error) { + var blocks []*B3Block + for _, d := range data { + var block B3Block + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &block); err != nil { + return nil, err + } + blocks = append(blocks, &block) + } + return blocks, nil +} + +func (c *Client) DecodeProtoEntireBlockToJson(rawData *bytes.Buffer) (*seer_common.BlocksBatchJson, error) { + var protoBlocksBatch B3BlocksBatch + + dataBytes := rawData.Bytes() + + err := proto.Unmarshal(dataBytes, &protoBlocksBatch) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal data: %v", err) + } + + blocksBatchJson := ToEntireBlocksBatchFromLogProto(&protoBlocksBatch) + + return blocksBatchJson, nil +} + +func (c *Client) DecodeProtoEntireBlockToLabels(rawData *bytes.Buffer, abiMap map[string]map[string]map[string]string) ([]indexer.EventLabel, []indexer.TransactionLabel, error) { + var protoBlocksBatch B3BlocksBatch + + dataBytes := rawData.Bytes() + + err := proto.Unmarshal(dataBytes, &protoBlocksBatch) + if err != nil { + return nil, nil, fmt.Errorf("failed to unmarshal data: %v", err) + } + + var labels []indexer.EventLabel + var txLabels []indexer.TransactionLabel + var decodeErr error + + for _, b := range protoBlocksBatch.Blocks { + for _, tx := range b.Transactions { + var decodedArgsTx map[string]interface{} + + label := indexer.SeerCrawlerLabel + + if len(tx.Input) < 10 { // If input is less than 3 characters then it direct transfer + continue + } + + // Process transaction labels + selector := tx.Input[:10] + + if abiMap[tx.ToAddress] != nil && abiMap[tx.ToAddress][selector] != nil { + txContractAbi, err := abi.JSON(strings.NewReader(abiMap[tx.ToAddress][selector]["abi"])) + if err != nil { + fmt.Println("Error initializing contract ABI transactions: ", err) + return nil, nil, err + } + + inputData, err := hex.DecodeString(tx.Input[2:]) + if err != nil { + fmt.Println("Error decoding input data: ", err) + return nil, nil, err + } + + decodedArgsTx, decodeErr = seer_common.DecodeTransactionInputDataToInterface(&txContractAbi, inputData) + if decodeErr != nil { + fmt.Println("Error decoding transaction not decoded data: ", tx.Hash, decodeErr) + decodedArgsTx = map[string]interface{}{ + "input_raw": tx, + "abi": abiMap[tx.ToAddress][selector]["abi"], + "selector": selector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + txLabelDataBytes, err := json.Marshal(decodedArgsTx) + if err != nil { + fmt.Println("Error converting decodedArgsTx to JSON: ", err) + return nil, nil, err + } + + // Convert transaction to label + transactionLabel := indexer.TransactionLabel{ + Address: tx.ToAddress, + BlockNumber: tx.BlockNumber, + BlockHash: tx.BlockHash, + CallerAddress: tx.FromAddress, + LabelName: abiMap[tx.ToAddress][selector]["abi_name"], + LabelType: "tx_call", + OriginAddress: tx.FromAddress, + Label: label, + TransactionHash: tx.Hash, + LabelData: string(txLabelDataBytes), // Convert JSON byte slice to string + BlockTimestamp: b.Timestamp, + } + + txLabels = append(txLabels, transactionLabel) + } + + // Process events + for _, e := range tx.Logs { + var decodedArgsLogs map[string]interface{} + label = indexer.SeerCrawlerLabel + + var topicSelector string + + if len(e.Topics) > 0 { + topicSelector = e.Topics[0] + } else { + // 0x0 is the default topic selector + topicSelector = "0x0" + } + + if abiMap[e.Address] == nil || abiMap[e.Address][topicSelector] == nil { + continue + } + + // Get the ABI string + contractAbi, err := abi.JSON(strings.NewReader(abiMap[e.Address][topicSelector]["abi"])) + if err != nil { + fmt.Println("Error initializing contract ABI: ", err) + return nil, nil, err + } + + + // Decode the event data + decodedArgsLogs, decodeErr = seer_common.DecodeLogArgsToLabelData(&contractAbi, e.Topics, e.Data) + if decodeErr != nil { + fmt.Println("Error decoding event not decoded data: ", e.TransactionHash, decodeErr) + decodedArgsLogs = map[string]interface{}{ + "input_raw": e, + "abi": abiMap[e.Address][topicSelector]["abi"], + "selector": topicSelector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + // Convert decodedArgsLogs map to JSON + labelDataBytes, err := json.Marshal(decodedArgsLogs) + if err != nil { + fmt.Println("Error converting decodedArgsLogs to JSON: ", err) + return nil, nil, err + } + + // Convert event to label + eventLabel := indexer.EventLabel{ + Label: label, + LabelName: abiMap[e.Address][topicSelector]["abi_name"], + LabelType: "event", + BlockNumber: e.BlockNumber, + BlockHash: e.BlockHash, + Address: e.Address, + OriginAddress: tx.FromAddress, + TransactionHash: e.TransactionHash, + LabelData: string(labelDataBytes), // Convert JSON byte slice to string + BlockTimestamp: b.Timestamp, + LogIndex: e.LogIndex, + } + + labels = append(labels, eventLabel) + } + } + } + + return labels, txLabels, nil +} + +func (c *Client) DecodeProtoTransactionsToLabels(transactions []string, blocksCache map[uint64]uint64, abiMap map[string]map[string]map[string]string) ([]indexer.TransactionLabel, error) { + + decodedTransactions, err := c.DecodeProtoTransactions(transactions) + + if err != nil { + return nil, err + } + + var labels []indexer.TransactionLabel + var decodedArgs map[string]interface{} + var decodeErr error + + + for _, transaction := range decodedTransactions { + + label := indexer.SeerCrawlerLabel + + selector := transaction.Input[:10] + + contractAbi, err := abi.JSON(strings.NewReader(abiMap[transaction.ToAddress][selector]["abi"])) + + if err != nil { + return nil, err + } + + inputData, err := hex.DecodeString(transaction.Input[2:]) + if err != nil { + fmt.Println("Error decoding input data: ", err) + return nil, err + } + + decodedArgs, decodeErr = seer_common.DecodeTransactionInputDataToInterface(&contractAbi, inputData) + + if decodeErr != nil { + fmt.Println("Error decoding transaction not decoded data: ", transaction.Hash, decodeErr) + decodedArgs = map[string]interface{}{ + "input_raw": transaction, + "abi": abiMap[transaction.ToAddress][selector]["abi"], + "selector": selector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + labelDataBytes, err := json.Marshal(decodedArgs) + if err != nil { + fmt.Println("Error converting decodedArgs to JSON: ", err) + return nil, err + } + + // Convert JSON byte slice to string + labelDataString := string(labelDataBytes) + + // Convert transaction to label + transactionLabel := indexer.TransactionLabel{ + Address: transaction.ToAddress, + BlockNumber: transaction.BlockNumber, + BlockHash: transaction.BlockHash, + CallerAddress: transaction.FromAddress, + LabelName: abiMap[transaction.ToAddress][selector]["abi_name"], + LabelType: "tx_call", + OriginAddress: transaction.FromAddress, + Label: label, + TransactionHash: transaction.Hash, + LabelData: labelDataString, + BlockTimestamp: blocksCache[transaction.BlockNumber], + } + + labels = append(labels, transactionLabel) + + } + + return labels, nil +} \ No newline at end of file diff --git a/blockchain/b3/b3_index_types.pb.go b/blockchain/b3/b3_index_types.pb.go new file mode 100644 index 0000000..f188f33 --- /dev/null +++ b/blockchain/b3/b3_index_types.pb.go @@ -0,0 +1,912 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v3.6.1 +// source: blockchain/b3/b3_index_types.proto + +package b3 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type B3TransactionAccessList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + StorageKeys []string `protobuf:"bytes,2,rep,name=storage_keys,json=storageKeys,proto3" json:"storage_keys,omitempty"` +} + +func (x *B3TransactionAccessList) Reset() { + *x = B3TransactionAccessList{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3TransactionAccessList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3TransactionAccessList) ProtoMessage() {} + +func (x *B3TransactionAccessList) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3TransactionAccessList.ProtoReflect.Descriptor instead. +func (*B3TransactionAccessList) Descriptor() ([]byte, []int) { + return file_blockchain_b3_b3_index_types_proto_rawDescGZIP(), []int{0} +} + +func (x *B3TransactionAccessList) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *B3TransactionAccessList) GetStorageKeys() []string { + if x != nil { + return x.StorageKeys + } + return nil +} + +// Represents a single transaction within a block +type B3Transaction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + BlockNumber uint64 `protobuf:"varint,2,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + FromAddress string `protobuf:"bytes,3,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty"` + ToAddress string `protobuf:"bytes,4,opt,name=to_address,json=toAddress,proto3" json:"to_address,omitempty"` + Gas string `protobuf:"bytes,5,opt,name=gas,proto3" json:"gas,omitempty"` // using string to handle big numeric values + GasPrice string `protobuf:"bytes,6,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + MaxFeePerGas string `protobuf:"bytes,7,opt,name=max_fee_per_gas,json=maxFeePerGas,proto3" json:"max_fee_per_gas,omitempty"` + MaxPriorityFeePerGas string `protobuf:"bytes,8,opt,name=max_priority_fee_per_gas,json=maxPriorityFeePerGas,proto3" json:"max_priority_fee_per_gas,omitempty"` + Input string `protobuf:"bytes,9,opt,name=input,proto3" json:"input,omitempty"` // could be a long text + Nonce string `protobuf:"bytes,10,opt,name=nonce,proto3" json:"nonce,omitempty"` + TransactionIndex uint64 `protobuf:"varint,11,opt,name=transaction_index,json=transactionIndex,proto3" json:"transaction_index,omitempty"` + TransactionType uint64 `protobuf:"varint,12,opt,name=transaction_type,json=transactionType,proto3" json:"transaction_type,omitempty"` + Value string `protobuf:"bytes,13,opt,name=value,proto3" json:"value,omitempty"` // using string to handle big numeric values + IndexedAt uint64 `protobuf:"varint,14,opt,name=indexed_at,json=indexedAt,proto3" json:"indexed_at,omitempty"` // using uint64 to represent timestamp + BlockTimestamp uint64 `protobuf:"varint,15,opt,name=block_timestamp,json=blockTimestamp,proto3" json:"block_timestamp,omitempty"` // using uint64 to represent timestam + BlockHash string `protobuf:"bytes,16,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` // Added field for block hash + ChainId string `protobuf:"bytes,17,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // Used as a field to match potential EIP-1559 transaction types + V string `protobuf:"bytes,18,opt,name=v,proto3" json:"v,omitempty"` // Used as a field to match potential EIP-1559 transaction types + R string `protobuf:"bytes,19,opt,name=r,proto3" json:"r,omitempty"` // Used as a field to match potential EIP-1559 transaction types + S string `protobuf:"bytes,20,opt,name=s,proto3" json:"s,omitempty"` // Used as a field to match potential EIP-1559 transaction types + AccessList []*B3TransactionAccessList `protobuf:"bytes,21,rep,name=access_list,json=accessList,proto3" json:"access_list,omitempty"` + YParity string `protobuf:"bytes,22,opt,name=y_parity,json=yParity,proto3" json:"y_parity,omitempty"` // Used as a field to match potential EIP-1559 transaction types + Logs []*B3EventLog `protobuf:"bytes,23,rep,name=logs,proto3" json:"logs,omitempty"` +} + +func (x *B3Transaction) Reset() { + *x = B3Transaction{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3Transaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3Transaction) ProtoMessage() {} + +func (x *B3Transaction) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3Transaction.ProtoReflect.Descriptor instead. +func (*B3Transaction) Descriptor() ([]byte, []int) { + return file_blockchain_b3_b3_index_types_proto_rawDescGZIP(), []int{1} +} + +func (x *B3Transaction) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *B3Transaction) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3Transaction) GetFromAddress() string { + if x != nil { + return x.FromAddress + } + return "" +} + +func (x *B3Transaction) GetToAddress() string { + if x != nil { + return x.ToAddress + } + return "" +} + +func (x *B3Transaction) GetGas() string { + if x != nil { + return x.Gas + } + return "" +} + +func (x *B3Transaction) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *B3Transaction) GetMaxFeePerGas() string { + if x != nil { + return x.MaxFeePerGas + } + return "" +} + +func (x *B3Transaction) GetMaxPriorityFeePerGas() string { + if x != nil { + return x.MaxPriorityFeePerGas + } + return "" +} + +func (x *B3Transaction) GetInput() string { + if x != nil { + return x.Input + } + return "" +} + +func (x *B3Transaction) GetNonce() string { + if x != nil { + return x.Nonce + } + return "" +} + +func (x *B3Transaction) GetTransactionIndex() uint64 { + if x != nil { + return x.TransactionIndex + } + return 0 +} + +func (x *B3Transaction) GetTransactionType() uint64 { + if x != nil { + return x.TransactionType + } + return 0 +} + +func (x *B3Transaction) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *B3Transaction) GetIndexedAt() uint64 { + if x != nil { + return x.IndexedAt + } + return 0 +} + +func (x *B3Transaction) GetBlockTimestamp() uint64 { + if x != nil { + return x.BlockTimestamp + } + return 0 +} + +func (x *B3Transaction) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *B3Transaction) GetChainId() string { + if x != nil { + return x.ChainId + } + return "" +} + +func (x *B3Transaction) GetV() string { + if x != nil { + return x.V + } + return "" +} + +func (x *B3Transaction) GetR() string { + if x != nil { + return x.R + } + return "" +} + +func (x *B3Transaction) GetS() string { + if x != nil { + return x.S + } + return "" +} + +func (x *B3Transaction) GetAccessList() []*B3TransactionAccessList { + if x != nil { + return x.AccessList + } + return nil +} + +func (x *B3Transaction) GetYParity() string { + if x != nil { + return x.YParity + } + return "" +} + +func (x *B3Transaction) GetLogs() []*B3EventLog { + if x != nil { + return x.Logs + } + return nil +} + +// Represents a single blockchain block +type B3Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockNumber uint64 `protobuf:"varint,1,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + Difficulty uint64 `protobuf:"varint,2,opt,name=difficulty,proto3" json:"difficulty,omitempty"` + ExtraData string `protobuf:"bytes,3,opt,name=extra_data,json=extraData,proto3" json:"extra_data,omitempty"` + GasLimit uint64 `protobuf:"varint,4,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + GasUsed uint64 `protobuf:"varint,5,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + BaseFeePerGas string `protobuf:"bytes,6,opt,name=base_fee_per_gas,json=baseFeePerGas,proto3" json:"base_fee_per_gas,omitempty"` // using string to handle big numeric values + Hash string `protobuf:"bytes,7,opt,name=hash,proto3" json:"hash,omitempty"` + LogsBloom string `protobuf:"bytes,8,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty"` + Miner string `protobuf:"bytes,9,opt,name=miner,proto3" json:"miner,omitempty"` + Nonce string `protobuf:"bytes,10,opt,name=nonce,proto3" json:"nonce,omitempty"` + ParentHash string `protobuf:"bytes,11,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` + ReceiptsRoot string `protobuf:"bytes,12,opt,name=receipts_root,json=receiptsRoot,proto3" json:"receipts_root,omitempty"` + Sha3Uncles string `protobuf:"bytes,13,opt,name=sha3_uncles,json=sha3Uncles,proto3" json:"sha3_uncles,omitempty"` + Size uint64 `protobuf:"varint,14,opt,name=size,proto3" json:"size,omitempty"` + StateRoot string `protobuf:"bytes,15,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"` + Timestamp uint64 `protobuf:"varint,16,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + TotalDifficulty string `protobuf:"bytes,17,opt,name=total_difficulty,json=totalDifficulty,proto3" json:"total_difficulty,omitempty"` + TransactionsRoot string `protobuf:"bytes,18,opt,name=transactions_root,json=transactionsRoot,proto3" json:"transactions_root,omitempty"` + IndexedAt uint64 `protobuf:"varint,19,opt,name=indexed_at,json=indexedAt,proto3" json:"indexed_at,omitempty"` // using uint64 to represent timestamp + Transactions []*B3Transaction `protobuf:"bytes,20,rep,name=transactions,proto3" json:"transactions,omitempty"` +} + +func (x *B3Block) Reset() { + *x = B3Block{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3Block) ProtoMessage() {} + +func (x *B3Block) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3Block.ProtoReflect.Descriptor instead. +func (*B3Block) Descriptor() ([]byte, []int) { + return file_blockchain_b3_b3_index_types_proto_rawDescGZIP(), []int{2} +} + +func (x *B3Block) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3Block) GetDifficulty() uint64 { + if x != nil { + return x.Difficulty + } + return 0 +} + +func (x *B3Block) GetExtraData() string { + if x != nil { + return x.ExtraData + } + return "" +} + +func (x *B3Block) GetGasLimit() uint64 { + if x != nil { + return x.GasLimit + } + return 0 +} + +func (x *B3Block) GetGasUsed() uint64 { + if x != nil { + return x.GasUsed + } + return 0 +} + +func (x *B3Block) GetBaseFeePerGas() string { + if x != nil { + return x.BaseFeePerGas + } + return "" +} + +func (x *B3Block) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *B3Block) GetLogsBloom() string { + if x != nil { + return x.LogsBloom + } + return "" +} + +func (x *B3Block) GetMiner() string { + if x != nil { + return x.Miner + } + return "" +} + +func (x *B3Block) GetNonce() string { + if x != nil { + return x.Nonce + } + return "" +} + +func (x *B3Block) GetParentHash() string { + if x != nil { + return x.ParentHash + } + return "" +} + +func (x *B3Block) GetReceiptsRoot() string { + if x != nil { + return x.ReceiptsRoot + } + return "" +} + +func (x *B3Block) GetSha3Uncles() string { + if x != nil { + return x.Sha3Uncles + } + return "" +} + +func (x *B3Block) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *B3Block) GetStateRoot() string { + if x != nil { + return x.StateRoot + } + return "" +} + +func (x *B3Block) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *B3Block) GetTotalDifficulty() string { + if x != nil { + return x.TotalDifficulty + } + return "" +} + +func (x *B3Block) GetTransactionsRoot() string { + if x != nil { + return x.TransactionsRoot + } + return "" +} + +func (x *B3Block) GetIndexedAt() uint64 { + if x != nil { + return x.IndexedAt + } + return 0 +} + +func (x *B3Block) GetTransactions() []*B3Transaction { + if x != nil { + return x.Transactions + } + return nil +} + +type B3EventLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // The address of the contract that generated the log + Topics []string `protobuf:"bytes,2,rep,name=topics,proto3" json:"topics,omitempty"` // Topics are indexed parameters during log generation + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // The data field from the log + BlockNumber uint64 `protobuf:"varint,4,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` // The block number where this log was in + TransactionHash string `protobuf:"bytes,5,opt,name=transaction_hash,json=transactionHash,proto3" json:"transaction_hash,omitempty"` // The hash of the transaction that generated this log + BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` // The hash of the block where this log was in + Removed bool `protobuf:"varint,7,opt,name=removed,proto3" json:"removed,omitempty"` // True if the log was reverted due to a chain reorganization + LogIndex uint64 `protobuf:"varint,8,opt,name=log_index,json=logIndex,proto3" json:"log_index,omitempty"` // The index of the log in the block + TransactionIndex uint64 `protobuf:"varint,9,opt,name=transaction_index,json=transactionIndex,proto3" json:"transaction_index,omitempty"` // The index of the transaction in the block +} + +func (x *B3EventLog) Reset() { + *x = B3EventLog{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3EventLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3EventLog) ProtoMessage() {} + +func (x *B3EventLog) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3EventLog.ProtoReflect.Descriptor instead. +func (*B3EventLog) Descriptor() ([]byte, []int) { + return file_blockchain_b3_b3_index_types_proto_rawDescGZIP(), []int{3} +} + +func (x *B3EventLog) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *B3EventLog) GetTopics() []string { + if x != nil { + return x.Topics + } + return nil +} + +func (x *B3EventLog) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +func (x *B3EventLog) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3EventLog) GetTransactionHash() string { + if x != nil { + return x.TransactionHash + } + return "" +} + +func (x *B3EventLog) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *B3EventLog) GetRemoved() bool { + if x != nil { + return x.Removed + } + return false +} + +func (x *B3EventLog) GetLogIndex() uint64 { + if x != nil { + return x.LogIndex + } + return 0 +} + +func (x *B3EventLog) GetTransactionIndex() uint64 { + if x != nil { + return x.TransactionIndex + } + return 0 +} + +type B3BlocksBatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Blocks []*B3Block `protobuf:"bytes,1,rep,name=blocks,proto3" json:"blocks,omitempty"` + SeerVersion string `protobuf:"bytes,2,opt,name=seer_version,json=seerVersion,proto3" json:"seer_version,omitempty"` +} + +func (x *B3BlocksBatch) Reset() { + *x = B3BlocksBatch{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3BlocksBatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3BlocksBatch) ProtoMessage() {} + +func (x *B3BlocksBatch) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_b3_index_types_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3BlocksBatch.ProtoReflect.Descriptor instead. +func (*B3BlocksBatch) Descriptor() ([]byte, []int) { + return file_blockchain_b3_b3_index_types_proto_rawDescGZIP(), []int{4} +} + +func (x *B3BlocksBatch) GetBlocks() []*B3Block { + if x != nil { + return x.Blocks + } + return nil +} + +func (x *B3BlocksBatch) GetSeerVersion() string { + if x != nil { + return x.SeerVersion + } + return "" +} + +var File_blockchain_b3_b3_index_types_proto protoreflect.FileDescriptor + +var file_blockchain_b3_b3_index_types_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x33, 0x2f, + 0x62, 0x33, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x17, 0x42, 0x33, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xd3, 0x05, 0x0a, + 0x0d, 0x42, 0x33, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, + 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, + 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, + 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, + 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x65, + 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, 0x47, 0x61, 0x73, 0x12, 0x36, 0x0a, + 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x66, 0x65, + 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x14, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x46, 0x65, 0x65, 0x50, + 0x65, 0x72, 0x47, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x29, + 0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x41, 0x74, 0x12, 0x27, + 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x76, 0x12, + 0x0c, 0x0a, 0x01, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, + 0x01, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x42, 0x33, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x69, + 0x74, 0x79, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x79, 0x50, 0x61, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x1f, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x42, 0x33, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, + 0x67, 0x73, 0x22, 0x8e, 0x05, 0x0a, 0x07, 0x42, 0x33, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x21, + 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, + 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x10, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, 0x47, 0x61, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x62, 0x6c, + 0x6f, 0x6f, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x73, 0x42, + 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x33, 0x5f, 0x75, + 0x6e, 0x63, 0x6c, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, + 0x33, 0x55, 0x6e, 0x63, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, + 0x6c, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x6f, 0x6f, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x13, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x32, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x42, 0x33, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0xa3, 0x02, 0x0a, 0x0a, 0x42, 0x33, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, + 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x11, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x54, 0x0a, 0x0d, 0x42, 0x33, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x0a, 0x06, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x33, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x65, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, + 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2d, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x65, 0x72, + 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x33, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_blockchain_b3_b3_index_types_proto_rawDescOnce sync.Once + file_blockchain_b3_b3_index_types_proto_rawDescData = file_blockchain_b3_b3_index_types_proto_rawDesc +) + +func file_blockchain_b3_b3_index_types_proto_rawDescGZIP() []byte { + file_blockchain_b3_b3_index_types_proto_rawDescOnce.Do(func() { + file_blockchain_b3_b3_index_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_blockchain_b3_b3_index_types_proto_rawDescData) + }) + return file_blockchain_b3_b3_index_types_proto_rawDescData +} + +var file_blockchain_b3_b3_index_types_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_blockchain_b3_b3_index_types_proto_goTypes = []any{ + (*B3TransactionAccessList)(nil), // 0: B3TransactionAccessList + (*B3Transaction)(nil), // 1: B3Transaction + (*B3Block)(nil), // 2: B3Block + (*B3EventLog)(nil), // 3: B3EventLog + (*B3BlocksBatch)(nil), // 4: B3BlocksBatch +} +var file_blockchain_b3_b3_index_types_proto_depIdxs = []int32{ + 0, // 0: B3Transaction.access_list:type_name -> B3TransactionAccessList + 3, // 1: B3Transaction.logs:type_name -> B3EventLog + 1, // 2: B3Block.transactions:type_name -> B3Transaction + 2, // 3: B3BlocksBatch.blocks:type_name -> B3Block + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_blockchain_b3_b3_index_types_proto_init() } +func file_blockchain_b3_b3_index_types_proto_init() { + if File_blockchain_b3_b3_index_types_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_blockchain_b3_b3_index_types_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*B3TransactionAccessList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_b3_index_types_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*B3Transaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_b3_index_types_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*B3Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_b3_index_types_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*B3EventLog); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_b3_index_types_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*B3BlocksBatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_blockchain_b3_b3_index_types_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_blockchain_b3_b3_index_types_proto_goTypes, + DependencyIndexes: file_blockchain_b3_b3_index_types_proto_depIdxs, + MessageInfos: file_blockchain_b3_b3_index_types_proto_msgTypes, + }.Build() + File_blockchain_b3_b3_index_types_proto = out.File + file_blockchain_b3_b3_index_types_proto_rawDesc = nil + file_blockchain_b3_b3_index_types_proto_goTypes = nil + file_blockchain_b3_b3_index_types_proto_depIdxs = nil +} diff --git a/blockchain/b3/b3_index_types.proto b/blockchain/b3/b3_index_types.proto new file mode 100644 index 0000000..e68262a --- /dev/null +++ b/blockchain/b3/b3_index_types.proto @@ -0,0 +1,78 @@ +syntax = "proto3"; + +option go_package = "github.com/moonstream-to/seer/blockchain/b3"; + + +message B3TransactionAccessList { + string address = 1; + repeated string storage_keys = 2; +} + +// Represents a single transaction within a block +message B3Transaction { + string hash = 1; + uint64 block_number = 2; + string from_address = 3; + string to_address = 4; + string gas = 5; // using string to handle big numeric values + string gas_price = 6; + string max_fee_per_gas = 7; + string max_priority_fee_per_gas = 8; + string input = 9; // could be a long text + string nonce = 10; + uint64 transaction_index = 11; + uint64 transaction_type = 12; + string value = 13; // using string to handle big numeric values + uint64 indexed_at = 14; // using uint64 to represent timestamp + uint64 block_timestamp = 15; // using uint64 to represent timestam + string block_hash = 16; // Added field for block hash + string chain_id = 17; // Used as a field to match potential EIP-1559 transaction types + string v = 18; // Used as a field to match potential EIP-1559 transaction types + string r = 19; // Used as a field to match potential EIP-1559 transaction types + string s = 20; // Used as a field to match potential EIP-1559 transaction types + repeated B3TransactionAccessList access_list = 21; + string y_parity = 22; // Used as a field to match potential EIP-1559 transaction types + repeated B3EventLog logs = 23; +} + +// Represents a single blockchain block +message B3Block { + uint64 block_number = 1; + uint64 difficulty = 2; + string extra_data = 3; + uint64 gas_limit = 4; + uint64 gas_used = 5; + string base_fee_per_gas = 6; // using string to handle big numeric values + string hash = 7; + string logs_bloom = 8; + string miner = 9; + string nonce = 10; + string parent_hash = 11; + string receipts_root = 12; + string sha3_uncles = 13; + uint64 size = 14; + string state_root = 15; + uint64 timestamp = 16; + string total_difficulty = 17; + string transactions_root = 18; + uint64 indexed_at = 19; // using uint64 to represent timestamp + repeated B3Transaction transactions = 20; +} + +message B3EventLog { + string address = 1; // The address of the contract that generated the log + repeated string topics = 2; // Topics are indexed parameters during log generation + string data = 3; // The data field from the log + uint64 block_number = 4; // The block number where this log was in + string transaction_hash = 5; // The hash of the transaction that generated this log + string block_hash = 6; // The hash of the block where this log was in + bool removed = 7; // True if the log was reverted due to a chain reorganization + uint64 log_index = 8; // The index of the log in the block + uint64 transaction_index = 9; // The index of the transaction in the block +} + +message B3BlocksBatch { + repeated B3Block blocks = 1; + + string seer_version = 2; +} diff --git a/blockchain/b3_sepolia/b3_sepolia.go b/blockchain/b3_sepolia/b3_sepolia.go new file mode 100644 index 0000000..58f71d2 --- /dev/null +++ b/blockchain/b3_sepolia/b3_sepolia.go @@ -0,0 +1,845 @@ +package b3_sepolia + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "log" + "math/big" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "google.golang.org/protobuf/proto" + + seer_common "github.com/moonstream-to/seer/blockchain/common" + "github.com/moonstream-to/seer/indexer" + "github.com/moonstream-to/seer/version" +) + +func NewClient(url string, timeout int) (*Client, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + rpcClient, err := rpc.DialContext(ctx, url) + if err != nil { + return nil, err + } + return &Client{rpcClient: rpcClient}, nil +} + +// Client is a wrapper around the Ethereum JSON-RPC client. + +type Client struct { + rpcClient *rpc.Client +} + +// Client common + +// ChainType returns the chain type. +func (c *Client) ChainType() string { + return "b3_sepolia" +} + +// Close closes the underlying RPC client. +func (c *Client) Close() { + c.rpcClient.Close() +} + +// GetLatestBlockNumber returns the latest block number. +func (c *Client) GetLatestBlockNumber() (*big.Int, error) { + var result string + if err := c.rpcClient.CallContext(context.Background(), &result, "eth_blockNumber"); err != nil { + return nil, err + } + + // Convert the hex string to a big.Int + blockNumber, ok := new(big.Int).SetString(result, 0) // The 0 base lets the function infer the base from the string prefix. + if !ok { + return nil, fmt.Errorf("invalid block number format: %s", result) + } + + return blockNumber, nil +} + +// BlockByNumber returns the block with the given number. +func (c *Client) GetBlockByNumber(ctx context.Context, number *big.Int) (*seer_common.BlockJson, error) { + + var rawResponse json.RawMessage // Use RawMessage to capture the entire JSON response + err := c.rpcClient.CallContext(ctx, &rawResponse, "eth_getBlockByNumber", "0x"+number.Text(16), true) + if err != nil { + fmt.Println("Error calling eth_getBlockByNumber: ", err) + return nil, err + } + + var response_json map[string]interface{} + + err = json.Unmarshal(rawResponse, &response_json) + + delete(response_json, "transactions") + + var block *seer_common.BlockJson + err = c.rpcClient.CallContext(ctx, &block, "eth_getBlockByNumber", "0x"+number.Text(16), true) // true to include transactions + return block, err +} + +// BlockByHash returns the block with the given hash. +func (c *Client) BlockByHash(ctx context.Context, hash common.Hash) (*seer_common.BlockJson, error) { + var block *seer_common.BlockJson + err := c.rpcClient.CallContext(ctx, &block, "eth_getBlockByHash", hash, true) // true to include transactions + return block, err +} + +// TransactionReceipt returns the receipt of a transaction by transaction hash. +func (c *Client) TransactionReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) { + var receipt *types.Receipt + err := c.rpcClient.CallContext(ctx, &receipt, "eth_getTransactionReceipt", hash) + return receipt, err +} + +func (c *Client) ClientFilterLogs(ctx context.Context, q ethereum.FilterQuery, debug bool) ([]*seer_common.EventJson, error) { + var logs []*seer_common.EventJson + fromBlock := q.FromBlock + toBlock := q.ToBlock + batchStep := new(big.Int).Sub(toBlock, fromBlock) // Calculate initial batch step + + for { + // Calculate the next "lastBlock" within the batch step or adjust to "toBlock" if exceeding + nextBlock := new(big.Int).Add(fromBlock, batchStep) + if nextBlock.Cmp(toBlock) > 0 { + nextBlock = new(big.Int).Set(toBlock) + } + + var result []*seer_common.EventJson + err := c.rpcClient.CallContext(ctx, &result, "eth_getLogs", struct { + FromBlock string `json:"fromBlock"` + ToBlock string `json:"toBlock"` + Addresses []common.Address `json:"addresses"` + Topics [][]common.Hash `json:"topics"` + }{ + FromBlock: toHex(fromBlock), + ToBlock: toHex(nextBlock), + Addresses: q.Addresses, + Topics: q.Topics, + }) + + if err != nil { + if strings.Contains(err.Error(), "query returned more than 10000 results") { + // Halve the batch step if too many results and retry + batchStep.Div(batchStep, big.NewInt(2)) + if batchStep.Cmp(big.NewInt(1)) < 0 { + // If the batch step is too small we will skip that block + fromBlock = new(big.Int).Add(nextBlock, big.NewInt(1)) + if fromBlock.Cmp(toBlock) > 0 { + break + } + continue + } + continue + } else { + // For any other error, return immediately + return nil, err + } + } + + // Append the results and adjust "fromBlock" for the next batch + logs = append(logs, result...) + fromBlock = new(big.Int).Add(nextBlock, big.NewInt(1)) + + if debug { + log.Printf("Fetched logs: %d", len(result)) + } + + // Break the loop if we've reached or exceeded "toBlock" + if fromBlock.Cmp(toBlock) > 0 { + break + } + } + + return logs, nil +} + +// Utility function to convert big.Int to its hexadecimal representation. +func toHex(number *big.Int) string { + return fmt.Sprintf("0x%x", number) +} + +func fromHex(hex string) *big.Int { + number := new(big.Int) + number.SetString(hex, 0) + return number +} + +// FetchBlocksInRange fetches blocks within a specified range. +// This could be useful for batch processing or analysis. +func (c *Client) FetchBlocksInRange(from, to *big.Int, debug bool) ([]*seer_common.BlockJson, error) { + var blocks []*seer_common.BlockJson + ctx := context.Background() // For simplicity, using a background context; consider timeouts for production. + + for i := new(big.Int).Set(from); i.Cmp(to) <= 0; i.Add(i, big.NewInt(1)) { + block, err := c.GetBlockByNumber(ctx, i) + if err != nil { + return nil, err + } + + blocks = append(blocks, block) + if debug { + log.Printf("Fetched block number: %d", i) + } + } + + return blocks, nil +} + +// FetchBlocksInRangeAsync fetches blocks within a specified range concurrently. +func (c *Client) FetchBlocksInRangeAsync(from, to *big.Int, debug bool, maxRequests int) ([]*seer_common.BlockJson, error) { + var ( + blocks []*seer_common.BlockJson + + mu sync.Mutex + wg sync.WaitGroup + ctx = context.Background() + ) + + var blockNumbersRange []*big.Int + for i := new(big.Int).Set(from); i.Cmp(to) <= 0; i.Add(i, big.NewInt(1)) { + blockNumbersRange = append(blockNumbersRange, new(big.Int).Set(i)) + } + + sem := make(chan struct{}, maxRequests) // Semaphore to control concurrency + errChan := make(chan error, 1) + + for _, b := range blockNumbersRange { + wg.Add(1) + go func(b *big.Int) { + defer wg.Done() + + sem <- struct{}{} // Acquire semaphore + + block, getErr := c.GetBlockByNumber(ctx, b) + if getErr != nil { + log.Printf("Failed to fetch block number: %d, error: %v", b, getErr) + errChan <- getErr + return + } + + mu.Lock() + blocks = append(blocks, block) + mu.Unlock() + + if debug { + log.Printf("Fetched block number: %d", b) + } + + <-sem + }(b) + } + + wg.Wait() + close(sem) + close(errChan) + + if err := <-errChan; err != nil { + return nil, err + } + + return blocks, nil +} + +// ParseBlocksWithTransactions parses blocks and their transactions into custom data structure. +// This method showcases how to handle and transform detailed block and transaction data. +func (c *Client) ParseBlocksWithTransactions(from, to *big.Int, debug bool, maxRequests int) ([]*B3SepoliaBlock, error) { + var blocksWithTxsJson []*seer_common.BlockJson + var fetchErr error + if maxRequests > 1 { + blocksWithTxsJson, fetchErr = c.FetchBlocksInRangeAsync(from, to, debug, maxRequests) + } else { + blocksWithTxsJson, fetchErr = c.FetchBlocksInRange(from, to, debug) + } + if fetchErr != nil { + return nil, fetchErr + } + + var parsedBlocks []*B3SepoliaBlock + for _, blockAndTxsJson := range blocksWithTxsJson { + // Convert BlockJson to Block and Transactions as required. + parsedBlock := ToProtoSingleBlock(blockAndTxsJson) + + for _, txJson := range blockAndTxsJson.Transactions { + txJson.BlockTimestamp = blockAndTxsJson.Timestamp + + parsedTransaction := ToProtoSingleTransaction(&txJson) + parsedBlock.Transactions = append(parsedBlock.Transactions, parsedTransaction) + } + + parsedBlocks = append(parsedBlocks, parsedBlock) + } + + return parsedBlocks, nil +} + +func (c *Client) ParseEvents(from, to *big.Int, blocksCache map[uint64]indexer.BlockCache, debug bool) ([]*B3SepoliaEventLog, error) { + logs, err := c.ClientFilterLogs(context.Background(), ethereum.FilterQuery{ + FromBlock: from, + ToBlock: to, + }, debug) + + if err != nil { + fmt.Println("Error fetching logs: ", err) + return nil, err + } + + var parsedEvents []*B3SepoliaEventLog + + for _, log := range logs { + parsedEvent := ToProtoSingleEventLog(log) + parsedEvents = append(parsedEvents, parsedEvent) + + } + + return parsedEvents, nil +} + +func (c *Client) FetchAsProtoBlocksWithEvents(from, to *big.Int, debug bool, maxRequests int) ([]proto.Message, []indexer.BlockIndex, uint64, error) { + blocks, err := c.ParseBlocksWithTransactions(from, to, debug, maxRequests) + if err != nil { + return nil, nil, 0, err + } + + var blocksSize uint64 + + blocksCache := make(map[uint64]indexer.BlockCache) + + for _, block := range blocks { + blocksCache[block.BlockNumber] = indexer.BlockCache{ + BlockNumber: block.BlockNumber, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + } // Assuming block.BlockNumber is int64 and block.Hash is string + } + + events, err := c.ParseEvents(from, to, blocksCache, debug) + if err != nil { + return nil, nil, 0, err + } + + var blocksProto []proto.Message + var blocksIndex []indexer.BlockIndex + + for bI, block := range blocks { + for _, tx := range block.Transactions { + for _, event := range events { + if tx.Hash == event.TransactionHash { + tx.Logs = append(tx.Logs, event) + } + } + } + + + // Prepare blocks to index + blocksIndex = append(blocksIndex, indexer.NewBlockIndex("b3_sepolia", + block.BlockNumber, + block.Hash, + block.Timestamp, + block.ParentHash, + uint64(bI), + "", + 0, + )) + + blocksSize += uint64(proto.Size(block)) + blocksProto = append(blocksProto, block) // Assuming block is already a proto.Message + } + + return blocksProto, blocksIndex, blocksSize, nil +} + +func (c *Client) ProcessBlocksToBatch(msgs []proto.Message) (proto.Message, error) { + var blocks []*B3SepoliaBlock + for _, msg := range msgs { + block, ok := msg.(*B3SepoliaBlock) + if !ok { + return nil, fmt.Errorf("failed to type assert proto.Message to *B3SepoliaBlock") + } + blocks = append(blocks, block) + } + + return &B3SepoliaBlocksBatch{ + Blocks: blocks, + SeerVersion: version.SeerVersion, + }, nil +} + +func ToEntireBlocksBatchFromLogProto(obj *B3SepoliaBlocksBatch) *seer_common.BlocksBatchJson { + blocksBatchJson := seer_common.BlocksBatchJson{ + Blocks: []seer_common.BlockJson{}, + SeerVersion: obj.SeerVersion, + } + + for _, b := range obj.Blocks { + var txs []seer_common.TransactionJson + for _, tx := range b.Transactions { + var accessList []seer_common.AccessList + for _, al := range tx.AccessList { + accessList = append(accessList, seer_common.AccessList{ + Address: al.Address, + StorageKeys: al.StorageKeys, + }) + } + var events []seer_common.EventJson + for _, e := range tx.Logs { + events = append(events, seer_common.EventJson{ + Address: e.Address, + Topics: e.Topics, + Data: e.Data, + BlockNumber: fmt.Sprintf("%d", e.BlockNumber), + TransactionHash: e.TransactionHash, + BlockHash: e.BlockHash, + Removed: e.Removed, + LogIndex: fmt.Sprintf("%d", e.LogIndex), + TransactionIndex: fmt.Sprintf("%d", e.TransactionIndex), + }) + } + txs = append(txs, seer_common.TransactionJson{ + BlockHash: tx.BlockHash, + BlockNumber: fmt.Sprintf("%d", tx.BlockNumber), + ChainId: tx.ChainId, + FromAddress: tx.FromAddress, + Gas: tx.Gas, + GasPrice: tx.GasPrice, + Hash: tx.Hash, + Input: tx.Input, + MaxFeePerGas: tx.MaxFeePerGas, + MaxPriorityFeePerGas: tx.MaxPriorityFeePerGas, + Nonce: tx.Nonce, + V: tx.V, + R: tx.R, + S: tx.S, + ToAddress: tx.ToAddress, + TransactionIndex: fmt.Sprintf("%d", tx.TransactionIndex), + TransactionType: fmt.Sprintf("%d", tx.TransactionType), + Value: tx.Value, + IndexedAt: fmt.Sprintf("%d", tx.IndexedAt), + BlockTimestamp: fmt.Sprintf("%d", tx.BlockTimestamp), + AccessList: accessList, + YParity: tx.YParity, + + Events: events, + }) + } + + blocksBatchJson.Blocks = append(blocksBatchJson.Blocks, seer_common.BlockJson{ + Difficulty: fmt.Sprintf("%d", b.Difficulty), + ExtraData: b.ExtraData, + GasLimit: fmt.Sprintf("%d", b.GasLimit), + GasUsed: fmt.Sprintf("%d", b.GasUsed), + Hash: b.Hash, + LogsBloom: b.LogsBloom, + Miner: b.Miner, + Nonce: b.Nonce, + BlockNumber: fmt.Sprintf("%d", b.BlockNumber), + ParentHash: b.ParentHash, + ReceiptsRoot: b.ReceiptsRoot, + Sha3Uncles: b.Sha3Uncles, + StateRoot: b.StateRoot, + Timestamp: fmt.Sprintf("%d", b.Timestamp), + TotalDifficulty: b.TotalDifficulty, + TransactionsRoot: b.TransactionsRoot, + Size: fmt.Sprintf("%d", b.Size), + BaseFeePerGas: b.BaseFeePerGas, + IndexedAt: fmt.Sprintf("%d", b.IndexedAt), + + + + + + + Transactions: txs, + }) + } + + return &blocksBatchJson +} + +func ToProtoSingleBlock(obj *seer_common.BlockJson) *B3SepoliaBlock { + return &B3SepoliaBlock{ + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + Difficulty: fromHex(obj.Difficulty).Uint64(), + ExtraData: obj.ExtraData, + GasLimit: fromHex(obj.GasLimit).Uint64(), + GasUsed: fromHex(obj.GasUsed).Uint64(), + BaseFeePerGas: obj.BaseFeePerGas, + Hash: obj.Hash, + LogsBloom: obj.LogsBloom, + Miner: obj.Miner, + Nonce: obj.Nonce, + ParentHash: obj.ParentHash, + ReceiptsRoot: obj.ReceiptsRoot, + Sha3Uncles: obj.Sha3Uncles, + Size: fromHex(obj.Size).Uint64(), + StateRoot: obj.StateRoot, + Timestamp: fromHex(obj.Timestamp).Uint64(), + TotalDifficulty: obj.TotalDifficulty, + TransactionsRoot: obj.TransactionsRoot, + IndexedAt: fromHex(obj.IndexedAt).Uint64(), + + + + + + } +} + +func ToProtoSingleTransaction(obj *seer_common.TransactionJson) *B3SepoliaTransaction { + var accessList []*B3SepoliaTransactionAccessList + for _, al := range obj.AccessList { + accessList = append(accessList, &B3SepoliaTransactionAccessList{ + Address: al.Address, + StorageKeys: al.StorageKeys, + }) + } + + return &B3SepoliaTransaction{ + Hash: obj.Hash, + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + BlockHash: obj.BlockHash, + FromAddress: obj.FromAddress, + ToAddress: obj.ToAddress, + Gas: obj.Gas, + GasPrice: obj.GasPrice, + MaxFeePerGas: obj.MaxFeePerGas, + MaxPriorityFeePerGas: obj.MaxPriorityFeePerGas, + Input: obj.Input, + Nonce: obj.Nonce, + TransactionIndex: fromHex(obj.TransactionIndex).Uint64(), + TransactionType: fromHex(obj.TransactionType).Uint64(), + Value: obj.Value, + IndexedAt: fromHex(obj.IndexedAt).Uint64(), + BlockTimestamp: fromHex(obj.BlockTimestamp).Uint64(), + + ChainId: obj.ChainId, + V: obj.V, + R: obj.R, + S: obj.S, + + AccessList: accessList, + YParity: obj.YParity, + } +} + +func ToEvenFromLogProto(obj *B3SepoliaEventLog) *seer_common.EventJson { + return &seer_common.EventJson{ + Address: obj.Address, + Topics: obj.Topics, + Data: obj.Data, + BlockNumber: fmt.Sprintf("%d", obj.BlockNumber), + TransactionHash: obj.TransactionHash, + LogIndex: fmt.Sprintf("%d", obj.LogIndex), + BlockHash: obj.BlockHash, + Removed: obj.Removed, + } +} + +func ToProtoSingleEventLog(obj *seer_common.EventJson) *B3SepoliaEventLog { + return &B3SepoliaEventLog{ + Address: obj.Address, + Topics: obj.Topics, + Data: obj.Data, + BlockNumber: fromHex(obj.BlockNumber).Uint64(), + TransactionHash: obj.TransactionHash, + LogIndex: fromHex(obj.LogIndex).Uint64(), + BlockHash: obj.BlockHash, + Removed: obj.Removed, + } +} + +func (c *Client) DecodeProtoEventLogs(data []string) ([]*B3SepoliaEventLog, error) { + var events []*B3SepoliaEventLog + for _, d := range data { + var event B3SepoliaEventLog + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &event); err != nil { + return nil, err + } + events = append(events, &event) + } + return events, nil +} + +func (c *Client) DecodeProtoTransactions(data []string) ([]*B3SepoliaTransaction, error) { + var transactions []*B3SepoliaTransaction + for _, d := range data { + var transaction B3SepoliaTransaction + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &transaction); err != nil { + return nil, err + } + transactions = append(transactions, &transaction) + } + return transactions, nil +} + +func (c *Client) DecodeProtoBlocks(data []string) ([]*B3SepoliaBlock, error) { + var blocks []*B3SepoliaBlock + for _, d := range data { + var block B3SepoliaBlock + base64Decoded, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return nil, err + } + if err := proto.Unmarshal(base64Decoded, &block); err != nil { + return nil, err + } + blocks = append(blocks, &block) + } + return blocks, nil +} + +func (c *Client) DecodeProtoEntireBlockToJson(rawData *bytes.Buffer) (*seer_common.BlocksBatchJson, error) { + var protoBlocksBatch B3SepoliaBlocksBatch + + dataBytes := rawData.Bytes() + + err := proto.Unmarshal(dataBytes, &protoBlocksBatch) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal data: %v", err) + } + + blocksBatchJson := ToEntireBlocksBatchFromLogProto(&protoBlocksBatch) + + return blocksBatchJson, nil +} + +func (c *Client) DecodeProtoEntireBlockToLabels(rawData *bytes.Buffer, abiMap map[string]map[string]map[string]string) ([]indexer.EventLabel, []indexer.TransactionLabel, error) { + var protoBlocksBatch B3SepoliaBlocksBatch + + dataBytes := rawData.Bytes() + + err := proto.Unmarshal(dataBytes, &protoBlocksBatch) + if err != nil { + return nil, nil, fmt.Errorf("failed to unmarshal data: %v", err) + } + + var labels []indexer.EventLabel + var txLabels []indexer.TransactionLabel + var decodeErr error + + for _, b := range protoBlocksBatch.Blocks { + for _, tx := range b.Transactions { + var decodedArgsTx map[string]interface{} + + label := indexer.SeerCrawlerLabel + + if len(tx.Input) < 10 { // If input is less than 3 characters then it direct transfer + continue + } + + // Process transaction labels + selector := tx.Input[:10] + + if abiMap[tx.ToAddress] != nil && abiMap[tx.ToAddress][selector] != nil { + txContractAbi, err := abi.JSON(strings.NewReader(abiMap[tx.ToAddress][selector]["abi"])) + if err != nil { + fmt.Println("Error initializing contract ABI transactions: ", err) + return nil, nil, err + } + + inputData, err := hex.DecodeString(tx.Input[2:]) + if err != nil { + fmt.Println("Error decoding input data: ", err) + return nil, nil, err + } + + decodedArgsTx, decodeErr = seer_common.DecodeTransactionInputDataToInterface(&txContractAbi, inputData) + if decodeErr != nil { + fmt.Println("Error decoding transaction not decoded data: ", tx.Hash, decodeErr) + decodedArgsTx = map[string]interface{}{ + "input_raw": tx, + "abi": abiMap[tx.ToAddress][selector]["abi"], + "selector": selector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + txLabelDataBytes, err := json.Marshal(decodedArgsTx) + if err != nil { + fmt.Println("Error converting decodedArgsTx to JSON: ", err) + return nil, nil, err + } + + // Convert transaction to label + transactionLabel := indexer.TransactionLabel{ + Address: tx.ToAddress, + BlockNumber: tx.BlockNumber, + BlockHash: tx.BlockHash, + CallerAddress: tx.FromAddress, + LabelName: abiMap[tx.ToAddress][selector]["abi_name"], + LabelType: "tx_call", + OriginAddress: tx.FromAddress, + Label: label, + TransactionHash: tx.Hash, + LabelData: string(txLabelDataBytes), // Convert JSON byte slice to string + BlockTimestamp: b.Timestamp, + } + + txLabels = append(txLabels, transactionLabel) + } + + // Process events + for _, e := range tx.Logs { + var decodedArgsLogs map[string]interface{} + label = indexer.SeerCrawlerLabel + + var topicSelector string + + if len(e.Topics) > 0 { + topicSelector = e.Topics[0] + } else { + // 0x0 is the default topic selector + topicSelector = "0x0" + } + + if abiMap[e.Address] == nil || abiMap[e.Address][topicSelector] == nil { + continue + } + + // Get the ABI string + contractAbi, err := abi.JSON(strings.NewReader(abiMap[e.Address][topicSelector]["abi"])) + if err != nil { + fmt.Println("Error initializing contract ABI: ", err) + return nil, nil, err + } + + + // Decode the event data + decodedArgsLogs, decodeErr = seer_common.DecodeLogArgsToLabelData(&contractAbi, e.Topics, e.Data) + if decodeErr != nil { + fmt.Println("Error decoding event not decoded data: ", e.TransactionHash, decodeErr) + decodedArgsLogs = map[string]interface{}{ + "input_raw": e, + "abi": abiMap[e.Address][topicSelector]["abi"], + "selector": topicSelector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + // Convert decodedArgsLogs map to JSON + labelDataBytes, err := json.Marshal(decodedArgsLogs) + if err != nil { + fmt.Println("Error converting decodedArgsLogs to JSON: ", err) + return nil, nil, err + } + + // Convert event to label + eventLabel := indexer.EventLabel{ + Label: label, + LabelName: abiMap[e.Address][topicSelector]["abi_name"], + LabelType: "event", + BlockNumber: e.BlockNumber, + BlockHash: e.BlockHash, + Address: e.Address, + OriginAddress: tx.FromAddress, + TransactionHash: e.TransactionHash, + LabelData: string(labelDataBytes), // Convert JSON byte slice to string + BlockTimestamp: b.Timestamp, + LogIndex: e.LogIndex, + } + + labels = append(labels, eventLabel) + } + } + } + + return labels, txLabels, nil +} + +func (c *Client) DecodeProtoTransactionsToLabels(transactions []string, blocksCache map[uint64]uint64, abiMap map[string]map[string]map[string]string) ([]indexer.TransactionLabel, error) { + + decodedTransactions, err := c.DecodeProtoTransactions(transactions) + + if err != nil { + return nil, err + } + + var labels []indexer.TransactionLabel + var decodedArgs map[string]interface{} + var decodeErr error + + + for _, transaction := range decodedTransactions { + + label := indexer.SeerCrawlerLabel + + selector := transaction.Input[:10] + + contractAbi, err := abi.JSON(strings.NewReader(abiMap[transaction.ToAddress][selector]["abi"])) + + if err != nil { + return nil, err + } + + inputData, err := hex.DecodeString(transaction.Input[2:]) + if err != nil { + fmt.Println("Error decoding input data: ", err) + return nil, err + } + + decodedArgs, decodeErr = seer_common.DecodeTransactionInputDataToInterface(&contractAbi, inputData) + + if decodeErr != nil { + fmt.Println("Error decoding transaction not decoded data: ", transaction.Hash, decodeErr) + decodedArgs = map[string]interface{}{ + "input_raw": transaction, + "abi": abiMap[transaction.ToAddress][selector]["abi"], + "selector": selector, + "error": decodeErr, + } + label = indexer.SeerCrawlerRawLabel + } + + labelDataBytes, err := json.Marshal(decodedArgs) + if err != nil { + fmt.Println("Error converting decodedArgs to JSON: ", err) + return nil, err + } + + // Convert JSON byte slice to string + labelDataString := string(labelDataBytes) + + // Convert transaction to label + transactionLabel := indexer.TransactionLabel{ + Address: transaction.ToAddress, + BlockNumber: transaction.BlockNumber, + BlockHash: transaction.BlockHash, + CallerAddress: transaction.FromAddress, + LabelName: abiMap[transaction.ToAddress][selector]["abi_name"], + LabelType: "tx_call", + OriginAddress: transaction.FromAddress, + Label: label, + TransactionHash: transaction.Hash, + LabelData: labelDataString, + BlockTimestamp: blocksCache[transaction.BlockNumber], + } + + labels = append(labels, transactionLabel) + + } + + return labels, nil +} \ No newline at end of file diff --git a/blockchain/b3_sepolia/b3_sepolia_index_types.pb.go b/blockchain/b3_sepolia/b3_sepolia_index_types.pb.go new file mode 100644 index 0000000..3084fec --- /dev/null +++ b/blockchain/b3_sepolia/b3_sepolia_index_types.pb.go @@ -0,0 +1,917 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v3.6.1 +// source: blockchain/b3_sepolia/b3_sepolia_index_types.proto + +package b3_sepolia + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type B3SepoliaTransactionAccessList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + StorageKeys []string `protobuf:"bytes,2,rep,name=storage_keys,json=storageKeys,proto3" json:"storage_keys,omitempty"` +} + +func (x *B3SepoliaTransactionAccessList) Reset() { + *x = B3SepoliaTransactionAccessList{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3SepoliaTransactionAccessList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3SepoliaTransactionAccessList) ProtoMessage() {} + +func (x *B3SepoliaTransactionAccessList) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3SepoliaTransactionAccessList.ProtoReflect.Descriptor instead. +func (*B3SepoliaTransactionAccessList) Descriptor() ([]byte, []int) { + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP(), []int{0} +} + +func (x *B3SepoliaTransactionAccessList) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *B3SepoliaTransactionAccessList) GetStorageKeys() []string { + if x != nil { + return x.StorageKeys + } + return nil +} + +// Represents a single transaction within a block +type B3SepoliaTransaction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + BlockNumber uint64 `protobuf:"varint,2,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + FromAddress string `protobuf:"bytes,3,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty"` + ToAddress string `protobuf:"bytes,4,opt,name=to_address,json=toAddress,proto3" json:"to_address,omitempty"` + Gas string `protobuf:"bytes,5,opt,name=gas,proto3" json:"gas,omitempty"` // using string to handle big numeric values + GasPrice string `protobuf:"bytes,6,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + MaxFeePerGas string `protobuf:"bytes,7,opt,name=max_fee_per_gas,json=maxFeePerGas,proto3" json:"max_fee_per_gas,omitempty"` + MaxPriorityFeePerGas string `protobuf:"bytes,8,opt,name=max_priority_fee_per_gas,json=maxPriorityFeePerGas,proto3" json:"max_priority_fee_per_gas,omitempty"` + Input string `protobuf:"bytes,9,opt,name=input,proto3" json:"input,omitempty"` // could be a long text + Nonce string `protobuf:"bytes,10,opt,name=nonce,proto3" json:"nonce,omitempty"` + TransactionIndex uint64 `protobuf:"varint,11,opt,name=transaction_index,json=transactionIndex,proto3" json:"transaction_index,omitempty"` + TransactionType uint64 `protobuf:"varint,12,opt,name=transaction_type,json=transactionType,proto3" json:"transaction_type,omitempty"` + Value string `protobuf:"bytes,13,opt,name=value,proto3" json:"value,omitempty"` // using string to handle big numeric values + IndexedAt uint64 `protobuf:"varint,14,opt,name=indexed_at,json=indexedAt,proto3" json:"indexed_at,omitempty"` // using uint64 to represent timestamp + BlockTimestamp uint64 `protobuf:"varint,15,opt,name=block_timestamp,json=blockTimestamp,proto3" json:"block_timestamp,omitempty"` // using uint64 to represent timestam + BlockHash string `protobuf:"bytes,16,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` // Added field for block hash + ChainId string `protobuf:"bytes,17,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // Used as a field to match potential EIP-1559 transaction types + V string `protobuf:"bytes,18,opt,name=v,proto3" json:"v,omitempty"` // Used as a field to match potential EIP-1559 transaction types + R string `protobuf:"bytes,19,opt,name=r,proto3" json:"r,omitempty"` // Used as a field to match potential EIP-1559 transaction types + S string `protobuf:"bytes,20,opt,name=s,proto3" json:"s,omitempty"` // Used as a field to match potential EIP-1559 transaction types + AccessList []*B3SepoliaTransactionAccessList `protobuf:"bytes,21,rep,name=access_list,json=accessList,proto3" json:"access_list,omitempty"` + YParity string `protobuf:"bytes,22,opt,name=y_parity,json=yParity,proto3" json:"y_parity,omitempty"` // Used as a field to match potential EIP-1559 transaction types + Logs []*B3SepoliaEventLog `protobuf:"bytes,23,rep,name=logs,proto3" json:"logs,omitempty"` +} + +func (x *B3SepoliaTransaction) Reset() { + *x = B3SepoliaTransaction{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3SepoliaTransaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3SepoliaTransaction) ProtoMessage() {} + +func (x *B3SepoliaTransaction) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3SepoliaTransaction.ProtoReflect.Descriptor instead. +func (*B3SepoliaTransaction) Descriptor() ([]byte, []int) { + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP(), []int{1} +} + +func (x *B3SepoliaTransaction) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *B3SepoliaTransaction) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3SepoliaTransaction) GetFromAddress() string { + if x != nil { + return x.FromAddress + } + return "" +} + +func (x *B3SepoliaTransaction) GetToAddress() string { + if x != nil { + return x.ToAddress + } + return "" +} + +func (x *B3SepoliaTransaction) GetGas() string { + if x != nil { + return x.Gas + } + return "" +} + +func (x *B3SepoliaTransaction) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *B3SepoliaTransaction) GetMaxFeePerGas() string { + if x != nil { + return x.MaxFeePerGas + } + return "" +} + +func (x *B3SepoliaTransaction) GetMaxPriorityFeePerGas() string { + if x != nil { + return x.MaxPriorityFeePerGas + } + return "" +} + +func (x *B3SepoliaTransaction) GetInput() string { + if x != nil { + return x.Input + } + return "" +} + +func (x *B3SepoliaTransaction) GetNonce() string { + if x != nil { + return x.Nonce + } + return "" +} + +func (x *B3SepoliaTransaction) GetTransactionIndex() uint64 { + if x != nil { + return x.TransactionIndex + } + return 0 +} + +func (x *B3SepoliaTransaction) GetTransactionType() uint64 { + if x != nil { + return x.TransactionType + } + return 0 +} + +func (x *B3SepoliaTransaction) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *B3SepoliaTransaction) GetIndexedAt() uint64 { + if x != nil { + return x.IndexedAt + } + return 0 +} + +func (x *B3SepoliaTransaction) GetBlockTimestamp() uint64 { + if x != nil { + return x.BlockTimestamp + } + return 0 +} + +func (x *B3SepoliaTransaction) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *B3SepoliaTransaction) GetChainId() string { + if x != nil { + return x.ChainId + } + return "" +} + +func (x *B3SepoliaTransaction) GetV() string { + if x != nil { + return x.V + } + return "" +} + +func (x *B3SepoliaTransaction) GetR() string { + if x != nil { + return x.R + } + return "" +} + +func (x *B3SepoliaTransaction) GetS() string { + if x != nil { + return x.S + } + return "" +} + +func (x *B3SepoliaTransaction) GetAccessList() []*B3SepoliaTransactionAccessList { + if x != nil { + return x.AccessList + } + return nil +} + +func (x *B3SepoliaTransaction) GetYParity() string { + if x != nil { + return x.YParity + } + return "" +} + +func (x *B3SepoliaTransaction) GetLogs() []*B3SepoliaEventLog { + if x != nil { + return x.Logs + } + return nil +} + +// Represents a single blockchain block +type B3SepoliaBlock struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockNumber uint64 `protobuf:"varint,1,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + Difficulty uint64 `protobuf:"varint,2,opt,name=difficulty,proto3" json:"difficulty,omitempty"` + ExtraData string `protobuf:"bytes,3,opt,name=extra_data,json=extraData,proto3" json:"extra_data,omitempty"` + GasLimit uint64 `protobuf:"varint,4,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + GasUsed uint64 `protobuf:"varint,5,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + BaseFeePerGas string `protobuf:"bytes,6,opt,name=base_fee_per_gas,json=baseFeePerGas,proto3" json:"base_fee_per_gas,omitempty"` // using string to handle big numeric values + Hash string `protobuf:"bytes,7,opt,name=hash,proto3" json:"hash,omitempty"` + LogsBloom string `protobuf:"bytes,8,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty"` + Miner string `protobuf:"bytes,9,opt,name=miner,proto3" json:"miner,omitempty"` + Nonce string `protobuf:"bytes,10,opt,name=nonce,proto3" json:"nonce,omitempty"` + ParentHash string `protobuf:"bytes,11,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` + ReceiptsRoot string `protobuf:"bytes,12,opt,name=receipts_root,json=receiptsRoot,proto3" json:"receipts_root,omitempty"` + Sha3Uncles string `protobuf:"bytes,13,opt,name=sha3_uncles,json=sha3Uncles,proto3" json:"sha3_uncles,omitempty"` + Size uint64 `protobuf:"varint,14,opt,name=size,proto3" json:"size,omitempty"` + StateRoot string `protobuf:"bytes,15,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"` + Timestamp uint64 `protobuf:"varint,16,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + TotalDifficulty string `protobuf:"bytes,17,opt,name=total_difficulty,json=totalDifficulty,proto3" json:"total_difficulty,omitempty"` + TransactionsRoot string `protobuf:"bytes,18,opt,name=transactions_root,json=transactionsRoot,proto3" json:"transactions_root,omitempty"` + IndexedAt uint64 `protobuf:"varint,19,opt,name=indexed_at,json=indexedAt,proto3" json:"indexed_at,omitempty"` // using uint64 to represent timestamp + Transactions []*B3SepoliaTransaction `protobuf:"bytes,20,rep,name=transactions,proto3" json:"transactions,omitempty"` +} + +func (x *B3SepoliaBlock) Reset() { + *x = B3SepoliaBlock{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3SepoliaBlock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3SepoliaBlock) ProtoMessage() {} + +func (x *B3SepoliaBlock) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3SepoliaBlock.ProtoReflect.Descriptor instead. +func (*B3SepoliaBlock) Descriptor() ([]byte, []int) { + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP(), []int{2} +} + +func (x *B3SepoliaBlock) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3SepoliaBlock) GetDifficulty() uint64 { + if x != nil { + return x.Difficulty + } + return 0 +} + +func (x *B3SepoliaBlock) GetExtraData() string { + if x != nil { + return x.ExtraData + } + return "" +} + +func (x *B3SepoliaBlock) GetGasLimit() uint64 { + if x != nil { + return x.GasLimit + } + return 0 +} + +func (x *B3SepoliaBlock) GetGasUsed() uint64 { + if x != nil { + return x.GasUsed + } + return 0 +} + +func (x *B3SepoliaBlock) GetBaseFeePerGas() string { + if x != nil { + return x.BaseFeePerGas + } + return "" +} + +func (x *B3SepoliaBlock) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *B3SepoliaBlock) GetLogsBloom() string { + if x != nil { + return x.LogsBloom + } + return "" +} + +func (x *B3SepoliaBlock) GetMiner() string { + if x != nil { + return x.Miner + } + return "" +} + +func (x *B3SepoliaBlock) GetNonce() string { + if x != nil { + return x.Nonce + } + return "" +} + +func (x *B3SepoliaBlock) GetParentHash() string { + if x != nil { + return x.ParentHash + } + return "" +} + +func (x *B3SepoliaBlock) GetReceiptsRoot() string { + if x != nil { + return x.ReceiptsRoot + } + return "" +} + +func (x *B3SepoliaBlock) GetSha3Uncles() string { + if x != nil { + return x.Sha3Uncles + } + return "" +} + +func (x *B3SepoliaBlock) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *B3SepoliaBlock) GetStateRoot() string { + if x != nil { + return x.StateRoot + } + return "" +} + +func (x *B3SepoliaBlock) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *B3SepoliaBlock) GetTotalDifficulty() string { + if x != nil { + return x.TotalDifficulty + } + return "" +} + +func (x *B3SepoliaBlock) GetTransactionsRoot() string { + if x != nil { + return x.TransactionsRoot + } + return "" +} + +func (x *B3SepoliaBlock) GetIndexedAt() uint64 { + if x != nil { + return x.IndexedAt + } + return 0 +} + +func (x *B3SepoliaBlock) GetTransactions() []*B3SepoliaTransaction { + if x != nil { + return x.Transactions + } + return nil +} + +type B3SepoliaEventLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // The address of the contract that generated the log + Topics []string `protobuf:"bytes,2,rep,name=topics,proto3" json:"topics,omitempty"` // Topics are indexed parameters during log generation + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // The data field from the log + BlockNumber uint64 `protobuf:"varint,4,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` // The block number where this log was in + TransactionHash string `protobuf:"bytes,5,opt,name=transaction_hash,json=transactionHash,proto3" json:"transaction_hash,omitempty"` // The hash of the transaction that generated this log + BlockHash string `protobuf:"bytes,6,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` // The hash of the block where this log was in + Removed bool `protobuf:"varint,7,opt,name=removed,proto3" json:"removed,omitempty"` // True if the log was reverted due to a chain reorganization + LogIndex uint64 `protobuf:"varint,8,opt,name=log_index,json=logIndex,proto3" json:"log_index,omitempty"` // The index of the log in the block + TransactionIndex uint64 `protobuf:"varint,9,opt,name=transaction_index,json=transactionIndex,proto3" json:"transaction_index,omitempty"` // The index of the transaction in the block +} + +func (x *B3SepoliaEventLog) Reset() { + *x = B3SepoliaEventLog{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3SepoliaEventLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3SepoliaEventLog) ProtoMessage() {} + +func (x *B3SepoliaEventLog) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3SepoliaEventLog.ProtoReflect.Descriptor instead. +func (*B3SepoliaEventLog) Descriptor() ([]byte, []int) { + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP(), []int{3} +} + +func (x *B3SepoliaEventLog) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *B3SepoliaEventLog) GetTopics() []string { + if x != nil { + return x.Topics + } + return nil +} + +func (x *B3SepoliaEventLog) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +func (x *B3SepoliaEventLog) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *B3SepoliaEventLog) GetTransactionHash() string { + if x != nil { + return x.TransactionHash + } + return "" +} + +func (x *B3SepoliaEventLog) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *B3SepoliaEventLog) GetRemoved() bool { + if x != nil { + return x.Removed + } + return false +} + +func (x *B3SepoliaEventLog) GetLogIndex() uint64 { + if x != nil { + return x.LogIndex + } + return 0 +} + +func (x *B3SepoliaEventLog) GetTransactionIndex() uint64 { + if x != nil { + return x.TransactionIndex + } + return 0 +} + +type B3SepoliaBlocksBatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Blocks []*B3SepoliaBlock `protobuf:"bytes,1,rep,name=blocks,proto3" json:"blocks,omitempty"` + SeerVersion string `protobuf:"bytes,2,opt,name=seer_version,json=seerVersion,proto3" json:"seer_version,omitempty"` +} + +func (x *B3SepoliaBlocksBatch) Reset() { + *x = B3SepoliaBlocksBatch{} + if protoimpl.UnsafeEnabled { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *B3SepoliaBlocksBatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*B3SepoliaBlocksBatch) ProtoMessage() {} + +func (x *B3SepoliaBlocksBatch) ProtoReflect() protoreflect.Message { + mi := &file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use B3SepoliaBlocksBatch.ProtoReflect.Descriptor instead. +func (*B3SepoliaBlocksBatch) Descriptor() ([]byte, []int) { + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP(), []int{4} +} + +func (x *B3SepoliaBlocksBatch) GetBlocks() []*B3SepoliaBlock { + if x != nil { + return x.Blocks + } + return nil +} + +func (x *B3SepoliaBlocksBatch) GetSeerVersion() string { + if x != nil { + return x.SeerVersion + } + return "" +} + +var File_blockchain_b3_sepolia_b3_sepolia_index_types_proto protoreflect.FileDescriptor + +var file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDesc = []byte{ + 0x0a, 0x32, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x33, 0x5f, + 0x73, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x2f, 0x62, 0x33, 0x5f, 0x73, 0x65, 0x70, 0x6f, 0x6c, + 0x69, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x1e, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, + 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x22, 0xe8, 0x05, 0x0a, 0x14, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, + 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, + 0x72, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, + 0x61, 0x78, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, 0x47, 0x61, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d, + 0x61, 0x78, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6d, + 0x61, 0x78, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, + 0x47, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, + 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x29, 0x0a, 0x10, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x0f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x76, 0x12, 0x0c, 0x0a, + 0x01, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x73, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x79, + 0x5f, 0x70, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x79, + 0x50, 0x61, 0x72, 0x69, 0x74, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x17, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x9c, + 0x05, 0x0a, 0x0e, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, + 0x75, 0x6c, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x10, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x50, 0x65, + 0x72, 0x47, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x73, + 0x5f, 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, + 0x67, 0x73, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x65, 0x72, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x70, 0x74, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, + 0x33, 0x5f, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x73, 0x68, 0x61, 0x33, 0x55, 0x6e, 0x63, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, + 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x42, 0x33, 0x53, 0x65, 0x70, + 0x6f, 0x6c, 0x69, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xaa, 0x02, + 0x0a, 0x11, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2b, 0x0a, + 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x62, 0x0a, 0x14, 0x42, 0x33, + 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x27, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x42, 0x33, 0x53, 0x65, 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, + 0x65, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x73, 0x65, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x35, + 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2d, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x65, 0x72, 0x2f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x33, 0x5f, 0x73, 0x65, + 0x70, 0x6f, 0x6c, 0x69, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescOnce sync.Once + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescData = file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDesc +) + +func file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescGZIP() []byte { + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescOnce.Do(func() { + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescData) + }) + return file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDescData +} + +var file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_goTypes = []any{ + (*B3SepoliaTransactionAccessList)(nil), // 0: B3SepoliaTransactionAccessList + (*B3SepoliaTransaction)(nil), // 1: B3SepoliaTransaction + (*B3SepoliaBlock)(nil), // 2: B3SepoliaBlock + (*B3SepoliaEventLog)(nil), // 3: B3SepoliaEventLog + (*B3SepoliaBlocksBatch)(nil), // 4: B3SepoliaBlocksBatch +} +var file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_depIdxs = []int32{ + 0, // 0: B3SepoliaTransaction.access_list:type_name -> B3SepoliaTransactionAccessList + 3, // 1: B3SepoliaTransaction.logs:type_name -> B3SepoliaEventLog + 1, // 2: B3SepoliaBlock.transactions:type_name -> B3SepoliaTransaction + 2, // 3: B3SepoliaBlocksBatch.blocks:type_name -> B3SepoliaBlock + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_init() } +func file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_init() { + if File_blockchain_b3_sepolia_b3_sepolia_index_types_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*B3SepoliaTransactionAccessList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*B3SepoliaTransaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*B3SepoliaBlock); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*B3SepoliaEventLog); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*B3SepoliaBlocksBatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_goTypes, + DependencyIndexes: file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_depIdxs, + MessageInfos: file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_msgTypes, + }.Build() + File_blockchain_b3_sepolia_b3_sepolia_index_types_proto = out.File + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_rawDesc = nil + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_goTypes = nil + file_blockchain_b3_sepolia_b3_sepolia_index_types_proto_depIdxs = nil +} diff --git a/blockchain/b3_sepolia/b3_sepolia_index_types.proto b/blockchain/b3_sepolia/b3_sepolia_index_types.proto new file mode 100644 index 0000000..6282c16 --- /dev/null +++ b/blockchain/b3_sepolia/b3_sepolia_index_types.proto @@ -0,0 +1,78 @@ +syntax = "proto3"; + +option go_package = "github.com/moonstream-to/seer/blockchain/b3_sepolia"; + + +message B3SepoliaTransactionAccessList { + string address = 1; + repeated string storage_keys = 2; +} + +// Represents a single transaction within a block +message B3SepoliaTransaction { + string hash = 1; + uint64 block_number = 2; + string from_address = 3; + string to_address = 4; + string gas = 5; // using string to handle big numeric values + string gas_price = 6; + string max_fee_per_gas = 7; + string max_priority_fee_per_gas = 8; + string input = 9; // could be a long text + string nonce = 10; + uint64 transaction_index = 11; + uint64 transaction_type = 12; + string value = 13; // using string to handle big numeric values + uint64 indexed_at = 14; // using uint64 to represent timestamp + uint64 block_timestamp = 15; // using uint64 to represent timestam + string block_hash = 16; // Added field for block hash + string chain_id = 17; // Used as a field to match potential EIP-1559 transaction types + string v = 18; // Used as a field to match potential EIP-1559 transaction types + string r = 19; // Used as a field to match potential EIP-1559 transaction types + string s = 20; // Used as a field to match potential EIP-1559 transaction types + repeated B3SepoliaTransactionAccessList access_list = 21; + string y_parity = 22; // Used as a field to match potential EIP-1559 transaction types + repeated B3SepoliaEventLog logs = 23; +} + +// Represents a single blockchain block +message B3SepoliaBlock { + uint64 block_number = 1; + uint64 difficulty = 2; + string extra_data = 3; + uint64 gas_limit = 4; + uint64 gas_used = 5; + string base_fee_per_gas = 6; // using string to handle big numeric values + string hash = 7; + string logs_bloom = 8; + string miner = 9; + string nonce = 10; + string parent_hash = 11; + string receipts_root = 12; + string sha3_uncles = 13; + uint64 size = 14; + string state_root = 15; + uint64 timestamp = 16; + string total_difficulty = 17; + string transactions_root = 18; + uint64 indexed_at = 19; // using uint64 to represent timestamp + repeated B3SepoliaTransaction transactions = 20; +} + +message B3SepoliaEventLog { + string address = 1; // The address of the contract that generated the log + repeated string topics = 2; // Topics are indexed parameters during log generation + string data = 3; // The data field from the log + uint64 block_number = 4; // The block number where this log was in + string transaction_hash = 5; // The hash of the transaction that generated this log + string block_hash = 6; // The hash of the block where this log was in + bool removed = 7; // True if the log was reverted due to a chain reorganization + uint64 log_index = 8; // The index of the log in the block + uint64 transaction_index = 9; // The index of the transaction in the block +} + +message B3SepoliaBlocksBatch { + repeated B3SepoliaBlock blocks = 1; + + string seer_version = 2; +} diff --git a/blockchain/handlers.go b/blockchain/handlers.go index 0d1680f..e3ae817 100644 --- a/blockchain/handlers.go +++ b/blockchain/handlers.go @@ -67,6 +67,12 @@ func NewClient(chain, url string, timeout int) (BlockchainClient, error) { } else if chain == "imx_zkevm_sepolia" { client, err := imx_zkevm_sepolia.NewClient(url, timeout) return client, err + } else if chain == "b3" { + client, err := imx_zkevm_sepolia.NewClient(url, timeout) + return client, err + } else if chain == "b3_sepolia" { + client, err := imx_zkevm_sepolia.NewClient(url, timeout) + return client, err } else { return nil, errors.New("unsupported chain type") } diff --git a/crawler/settings.go b/crawler/settings.go index efb546f..cfad824 100644 --- a/crawler/settings.go +++ b/crawler/settings.go @@ -79,6 +79,16 @@ func CheckVariablesForCrawler() error { return fmt.Errorf("MOONSTREAM_NODE_GAME7_TESTNET_A_EXTERNAL_URI environment variable is required") } + MOONSTREAM_NODE_B3_A_EXTERNAL_URI := os.Getenv("MOONSTREAM_NODE_B3_A_EXTERNAL_URI") + if MOONSTREAM_NODE_B3_A_EXTERNAL_URI == "" { + return fmt.Errorf("MOONSTREAM_NODE_B3_A_EXTERNAL_URI environment variable is required") + } + + MOONSTREAM_NODE_B3_SEPOLIA_A_EXTERNAL_URI := os.Getenv("MOONSTREAM_NODE_B3_SEPOLIA_A_EXTERNAL_URI") + if MOONSTREAM_NODE_B3_SEPOLIA_A_EXTERNAL_URI == "" { + return fmt.Errorf("MOONSTREAM_NODE_B3_SEPOLIA_A_EXTERNAL_URI environment variable is required") + } + SEER_CRAWLER_DEBUG_RAW := os.Getenv("SEER_CRAWLER_DEBUG") SEER_CRAWLER_DEBUG, _ = strconv.ParseBool(SEER_CRAWLER_DEBUG_RAW) @@ -96,6 +106,8 @@ func CheckVariablesForCrawler() error { "mantle_sepolia": MOONSTREAM_NODE_MANTLE_SEPOLIA_A_EXTERNAL_URI, "imx_zkevm": MOONSTREAM_NODE_IMX_ZKEVM_A_EXTERNAL_URI, "imx_zkevm_sepolia": MOONSTREAM_NODE_IMX_ZKEVM_SEPOLIA_A_EXTERNAL_URI, + "b3": MOONSTREAM_NODE_B3_A_EXTERNAL_URI, + "b3_sepolia": MOONSTREAM_NODE_B3_SEPOLIA_A_EXTERNAL_URI, } return nil diff --git a/deploy/deploy.bash b/deploy/deploy.bash index aa72c9a..8b8c9e7 100755 --- a/deploy/deploy.bash +++ b/deploy/deploy.bash @@ -35,6 +35,8 @@ SEER_CRAWLER_XAI_SERVICE_FILE="seer-crawler-xai.service" SEER_CRAWLER_SEPOLIA_SERVICE_FILE="seer-crawler-sepolia.service" SEER_CRAWLER_IMX_ZKEVM_SERVICE_FILE="seer-crawler-imx-zkevm.service" SEER_CRAWLER_IMX_ZKEVM_SEPOLIA_SERVICE_FILE="seer-crawler-imx-zkevm-sepolia.service" +SEER_CRAWLER_B3_SERVICE_FILE="seer-crawler-b3.service" +SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE="seer-crawler-b3-sepolia.service" # Synchronizer SEER_SYNCHRONIZER_ETHEREUM_SERVICE_FILE="seer-synchronizer-ethereum.service" @@ -49,6 +51,8 @@ SEER_SYNCHRONIZER_XAI_SERVICE_FILE="seer-synchronizer-xai.service" SEER_SYNCHRONIZER_SEPOLIA_SERVICE_FILE="seer-synchronizer-sepolia.service" SEER_SYNCHRONIZER_IMX_ZKEVM_SERVICE_FILE="seer-synchronizer-imx-zkevm.service" SEER_SYNCHRONIZER_IMX_ZKEVM_SEPOLIA_SERVICE_FILE="seer-synchronizer-imx-zkevm-sepolia.service" +SEER_SYNCHRONIZER_B3_SERVICE_FILE="seer-synchronizer-b3.service" +SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE="seer-synchronizer-b3-sepolia.service" set -eu @@ -232,6 +236,21 @@ cp "${SCRIPT_DIR}/${SEER_CRAWLER_GAME7_TESTNET_SERVICE_FILE}" "${USER_SYSTEMD_DI XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_CRAWLER_GAME7_TESTNET_SERVICE_FILE}" +echo +echo +echo -e "${PREFIX_INFO} Replacing existing seer crawler for B3 blockchain service definition with ${SEER_CRAWLER_B3_SERVICE_FILE}" +chmod 644 "${SCRIPT_DIR}/${SEER_CRAWLER_B3_SERVICE_FILE}" +cp "${SCRIPT_DIR}/${SEER_CRAWLER_B3_SERVICE_FILE}" "${USER_SYSTEMD_DIR}/${SEER_CRAWLER_B3_SERVICE_FILE}" +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_CRAWLER_B3_SERVICE_FILE}" + +echo +echo +echo -e "${PREFIX_INFO} Replacing existing seer crawler for B3 Sepolia blockchain service definition with ${SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE}" +chmod 644 "${SCRIPT_DIR}/${SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE}" +cp "${SCRIPT_DIR}/${SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE}" "${USER_SYSTEMD_DIR}/${SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE}" +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_CRAWLER_B3_SEPOLIA_SERVICE_FILE}" # Synchronizers @@ -331,4 +350,20 @@ echo -e "${PREFIX_INFO} Replacing existing seer synchronizer for Game7 Testnet b chmod 644 "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_GAME7_TESTNET_SERVICE_FILE}" cp "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_GAME7_TESTNET_SERVICE_FILE}" "${USER_SYSTEMD_DIR}/${SEER_SYNCHRONIZER_GAME7_TESTNET_SERVICE_FILE}" XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload -XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_SYNCHRONIZER_GAME7_TESTNET_SERVICE_FILE}" \ No newline at end of file +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_SYNCHRONIZER_GAME7_TESTNET_SERVICE_FILE}" + +echo +echo +echo -e "${PREFIX_INFO} Replacing existing seer synchronizer for B3 blockchain service definition with ${SEER_SYNCHRONIZER_B3_SERVICE_FILE}" +chmod 644 "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_B3_SERVICE_FILE}" +cp "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_B3_SERVICE_FILE}" "${USER_SYSTEMD_DIR}/${SEER_SYNCHRONIZER_B3_SERVICE_FILE}" +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_SYNCHRONIZER_B3_SERVICE_FILE}" + +echo +echo +echo -e "${PREFIX_INFO} Replacing existing seer synchronizer for B3 Sepolia blockchain service definition with ${SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE}" +chmod 644 "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE}" +cp "${SCRIPT_DIR}/${SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE}" "${USER_SYSTEMD_DIR}/${SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE}" +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload +XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart "${SEER_SYNCHRONIZER_B3_SEPOLIA_SERVICE_FILE}" \ No newline at end of file diff --git a/deploy/monitoring-seer-crawlers.service b/deploy/monitoring-seer-crawlers.service index f8e808c..9623ff7 100644 --- a/deploy/monitoring-seer-crawlers.service +++ b/deploy/monitoring-seer-crawlers.service @@ -9,7 +9,7 @@ Restart=on-failure RestartSec=15s WorkingDirectory=/home/ubuntu/ EnvironmentFile=/home/ubuntu/seer-secrets/monitoring.env -ExecStart=/home/ubuntu/monitoring -plugin systemd -host "127.0.0.1" -port 7171 -healthcheck -server -threshold 3 -config /home/ubuntu/.monitoring/monitoring-seer-crawlers-config.json -service seer-crawler-arbitrum-one.service -service seer-crawler-arbitrum-sepolia.service -service seer-crawler-ethereum.service -service seer-crawler-imx-zkevm-sepolia.service -service seer-crawler-imx-zkevm.service -service seer-crawler-mantle-sepolia.service -service seer-crawler-mantle.service -service seer-crawler-polygon.service -service seer-crawler-sepolia.service -service seer-crawler-xai-sepolia.service -service seer-crawler-xai.service -service seer-synchronizer-arbitrum-one.service -service seer-synchronizer-arbitrum-sepolia.service -service seer-synchronizer-ethereum.service -service seer-synchronizer-imx-zkevm-sepolia.service -service seer-synchronizer-imx-zkevm.service -service seer-synchronizer-mantle-sepolia.service -service seer-synchronizer-mantle.service -service seer-synchronizer-polygon.service -service seer-synchronizer-sepolia.service -service seer-synchronizer-xai-sepolia.service -service seer-synchronizer-xai.service -service seer-crawler-game7-testnet.service -service seer-synchronizer-game7-testnet.service +ExecStart=/home/ubuntu/monitoring -plugin systemd -host "127.0.0.1" -port 7171 -healthcheck -server -threshold 3 -config /home/ubuntu/.monitoring/monitoring-seer-crawlers-config.json -service seer-crawler-arbitrum-one.service -service seer-crawler-arbitrum-sepolia.service -service seer-crawler-ethereum.service -service seer-crawler-imx-zkevm-sepolia.service -service seer-crawler-imx-zkevm.service -service seer-crawler-mantle-sepolia.service -service seer-crawler-mantle.service -service seer-crawler-polygon.service -service seer-crawler-sepolia.service -service seer-crawler-xai-sepolia.service -service seer-crawler-xai.service -service seer-synchronizer-arbitrum-one.service -service seer-synchronizer-arbitrum-sepolia.service -service seer-synchronizer-ethereum.service -service seer-synchronizer-imx-zkevm-sepolia.service -service seer-synchronizer-imx-zkevm.service -service seer-synchronizer-mantle-sepolia.service -service seer-synchronizer-mantle.service -service seer-synchronizer-polygon.service -service seer-synchronizer-sepolia.service -service seer-synchronizer-xai-sepolia.service -service seer-synchronizer-xai.service -service seer-crawler-game7-testnet.service -service seer-synchronizer-game7-testnet.service -service seer-crawler-b3.service -service seer-synchronizer-b3.service -service seer-crawler-b3-sepolia.service -service seer-synchronizer-b3-sepolia.service CPUWeight=90 SyslogIdentifier=monitoring-seer-crawlers diff --git a/deploy/seer-crawler-b3-sepolia.service b/deploy/seer-crawler-b3-sepolia.service new file mode 100644 index 0000000..e69de29 diff --git a/deploy/seer-crawler-b3.service b/deploy/seer-crawler-b3.service new file mode 100644 index 0000000..e69de29 diff --git a/deploy/seer-synchronizer-b3-sepolia.service b/deploy/seer-synchronizer-b3-sepolia.service new file mode 100644 index 0000000..e69de29 diff --git a/deploy/seer-synchronizer-b3.service b/deploy/seer-synchronizer-b3.service new file mode 100644 index 0000000..e69de29 diff --git a/indexer/db.go b/indexer/db.go index 03041ef..88d6807 100644 --- a/indexer/db.go +++ b/indexer/db.go @@ -72,6 +72,10 @@ func IsBlockchainWithL1Chain(blockchain string) bool { return false case "mantle_sepolia": return false + case "b3": + return false + case "b3_sepolia": + return false default: return false } diff --git a/prepare_blockchains.sh b/prepare_blockchains.sh index 8bdd7a1..40a8881 100755 --- a/prepare_blockchains.sh +++ b/prepare_blockchains.sh @@ -12,7 +12,7 @@ done BLOCKCHAIN_NAMES_RAW=$(find blockchain/ -maxdepth 1 -type d | cut -f2 -d '/') for BLOCKCHAIN in $BLOCKCHAIN_NAMES_RAW; do if [ "$BLOCKCHAIN" != "" ] && [ "$BLOCKCHAIN" != "common" ]; then - if [ "$BLOCKCHAIN" != "ethereum" ] && [ "$BLOCKCHAIN" != "polygon" ] && [ "$BLOCKCHAIN" != "mantle" ] && [ "$BLOCKCHAIN" != "mantle_sepolia" ] && [ "$BLOCKCHAIN" != "sepolia" ] && [ "$BLOCKCHAIN" != "imx_zkevm" ] && [ "$BLOCKCHAIN" != "imx_zkevm_sepolia" ]; then + if [ "$BLOCKCHAIN" != "ethereum" ] && [ "$BLOCKCHAIN" != "polygon" ] && [ "$BLOCKCHAIN" != "mantle" ] && [ "$BLOCKCHAIN" != "mantle_sepolia" ] && [ "$BLOCKCHAIN" != "sepolia" ] && [ "$BLOCKCHAIN" != "imx_zkevm" ] && [ "$BLOCKCHAIN" != "imx_zkevm_sepolia" ] && [ "$BLOCKCHAIN" != "b3" ] && [ "$BLOCKCHAIN" != "b3_sepolia" ]; then ./seer blockchain generate -n $BLOCKCHAIN --side-chain echo "Generated interface for side-chain blockchain $BLOCKCHAIN" else diff --git a/sample.env b/sample.env index 2be5a58..85302c7 100644 --- a/sample.env +++ b/sample.env @@ -14,6 +14,8 @@ export MOONSTREAM_NODE_MANTLE_SEPOLIA_A_EXTERNAL_URI="https:// Date: Wed, 11 Sep 2024 18:51:29 +0300 Subject: [PATCH 2/3] Update deploy scripts. --- deploy/seer-crawler-b3-sepolia.service | 16 ++++++++++++++++ deploy/seer-crawler-b3.service | 16 ++++++++++++++++ deploy/seer-synchronizer-b3-sepolia.service | 16 ++++++++++++++++ deploy/seer-synchronizer-b3.service | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/deploy/seer-crawler-b3-sepolia.service b/deploy/seer-crawler-b3-sepolia.service index e69de29..1a45d4b 100644 --- a/deploy/seer-crawler-b3-sepolia.service +++ b/deploy/seer-crawler-b3-sepolia.service @@ -0,0 +1,16 @@ +[Unit] +Description=Seer crawler service for B3 Sepolia blockchain +After=network.target +StartLimitIntervalSec=300 +StartLimitBurst=3 + +[Service] +WorkingDirectory=/home/ubuntu/seer +EnvironmentFile=/home/ubuntu/seer-secrets/app.env +Restart=on-failure +RestartSec=15s +ExecStart=/home/ubuntu/seer/seer crawler --chain b3_sepolia --confirmations 10 --threads 2 +SyslogIdentifier=seer-crawler-b3-sepolia + +[Install] +WantedBy=multi-user.target diff --git a/deploy/seer-crawler-b3.service b/deploy/seer-crawler-b3.service index e69de29..7c58766 100644 --- a/deploy/seer-crawler-b3.service +++ b/deploy/seer-crawler-b3.service @@ -0,0 +1,16 @@ +[Unit] +Description=Seer crawler service for B3 blockchain +After=network.target +StartLimitIntervalSec=300 +StartLimitBurst=3 + +[Service] +WorkingDirectory=/home/ubuntu/seer +EnvironmentFile=/home/ubuntu/seer-secrets/app.env +Restart=on-failure +RestartSec=15s +ExecStart=/home/ubuntu/seer/seer crawler --chain b3 --confirmations 10 --threads 2 +SyslogIdentifier=seer-crawler-b3 + +[Install] +WantedBy=multi-user.target diff --git a/deploy/seer-synchronizer-b3-sepolia.service b/deploy/seer-synchronizer-b3-sepolia.service index e69de29..4147a4b 100644 --- a/deploy/seer-synchronizer-b3-sepolia.service +++ b/deploy/seer-synchronizer-b3-sepolia.service @@ -0,0 +1,16 @@ +[Unit] +Description=Seer synchronizer service for b3 sepolia blockchain +After=network.target +StartLimitIntervalSec=300 +StartLimitBurst=3 + +[Service] +WorkingDirectory=/home/ubuntu/seer +EnvironmentFile=/home/ubuntu/seer-secrets/app.env +Restart=on-failure +RestartSec=15s +ExecStart=/home/ubuntu/seer/seer synchronizer --chain b3_sepolia +SyslogIdentifier=seer-synchronizer-ab3-sepolia + +[Install] +WantedBy=multi-user.target diff --git a/deploy/seer-synchronizer-b3.service b/deploy/seer-synchronizer-b3.service index e69de29..055b3c7 100644 --- a/deploy/seer-synchronizer-b3.service +++ b/deploy/seer-synchronizer-b3.service @@ -0,0 +1,16 @@ +[Unit] +Description=Seer synchronizer service for b3 blockchain +After=network.target +StartLimitIntervalSec=300 +StartLimitBurst=3 + +[Service] +WorkingDirectory=/home/ubuntu/seer +EnvironmentFile=/home/ubuntu/seer-secrets/app.env +Restart=on-failure +RestartSec=15s +ExecStart=/home/ubuntu/seer/seer synchronizer --chain b3 +SyslogIdentifier=seer-synchronizer-b3 + +[Install] +WantedBy=multi-user.target From 6b76b680350c5a5bb7f4a4d4b63dd4b1a4597d92 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 11 Sep 2024 18:52:32 +0300 Subject: [PATCH 3/3] Bump version. --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index e6b5f38..b1723b9 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,3 @@ package version -var SeerVersion string = "0.1.19" +var SeerVersion string = "0.1.20"