Skip to content

Commit

Permalink
Implement the storage interface for sqlite
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmcgary committed Sep 6, 2024
1 parent e8d78b4 commit 2ab3318
Showing 1 changed file with 164 additions and 7 deletions.
171 changes: 164 additions & 7 deletions internal/storage/sqlite/storage.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package sqlite

import (
"encoding/json"
"errors"
"fmt"
"github.com/Layr-Labs/sidecar/internal/config"
"github.com/Layr-Labs/sidecar/internal/parser"
"github.com/Layr-Labs/sidecar/internal/storage"
"go.uber.org/zap"
"golang.org/x/xerrors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"strings"
"time"
)

type SqliteBlockStoreConfig struct {
Expand All @@ -26,22 +35,170 @@ func NewSqliteBlockStore(db *gorm.DB, l *zap.Logger, cfg *config.Config) *Sqlite
return bs
}

/*
func (s *SqliteBlockStore) InsertBlockAtHeight(blockNumber uint64, hash string, blockTime uint64) (*storage.Block, error) {
func (s *SqliteBlockStore) InsertBlockAtHeight(
blockNumber uint64,
hash string,
blockTime uint64,
) (*storage.Block, error) {
block := &storage.Block{
Number: blockNumber,
Hash: hash,
BlockTime: time.Unix(int64(blockTime), 0),
}

res := s.Db.Model(&storage.Block{}).Clauses(clause.Returning{}).Create(&block)

if res.Error != nil {
return nil, fmt.Errorf("failed to insert block with number '%d': %w", blockNumber, res.Error)
}
return block, nil
}
func (s *SqliteBlockStore) InsertBlockTransaction(blockNumber uint64, txHash string, txIndex uint64, from string, to string, contractAddress string, bytecodeHash string) (*storage.Transaction, error) {

func (s *SqliteBlockStore) InsertBlockTransaction(
blockNumber uint64,
txHash string,
txIndex uint64,
from string,
to string,
contractAddress string,
bytecodeHash string,
) (*storage.Transaction, error) {
to = strings.ToLower(to)
from = strings.ToLower(from)
contractAddress = strings.ToLower(contractAddress)

tx := &storage.Transaction{
BlockNumber: blockNumber,
TransactionHash: txHash,
TransactionIndex: txIndex,
FromAddress: from,
ToAddress: to,
ContractAddress: contractAddress,
BytecodeHash: bytecodeHash,
}

result := s.Db.Model(&storage.Transaction{}).Clauses(clause.Returning{}).Create(&tx)

if result.Error != nil {
return nil, xerrors.Errorf("Failed to insert block transaction '%d' - '%s': %w", blockNumber, txHash, result.Error)
}
return tx, nil
}
func (s *SqliteBlockStore) InsertTransactionLog(txHash string, transactionIndex uint64, blockNumber uint64, log *parser.DecodedLog, outputData map[string]interface{}) (*storage.Transaction, error) {

func (s *SqliteBlockStore) InsertTransactionLog(
txHash string,
transactionIndex uint64,
blockNumber uint64,
log *parser.DecodedLog,
outputData map[string]interface{},
) (*storage.TransactionLog, error) {
argsJson, err := json.Marshal(log.Arguments)
if err != nil {
s.Logger.Sugar().Errorw("Failed to marshal arguments", zap.Error(err))
}

outputDataJson := []byte{}
outputDataJson, err = json.Marshal(outputData)
if err != nil {
s.Logger.Sugar().Errorw("Failed to marshal output data", zap.Error(err))
}

txLog := &storage.TransactionLog{
TransactionHash: txHash,
TransactionIndex: transactionIndex,
BlockNumber: blockNumber,
Address: strings.ToLower(log.Address),
Arguments: string(argsJson),
EventName: log.EventName,
LogIndex: log.LogIndex,
OutputData: string(outputDataJson),
}
result := s.Db.Model(&storage.TransactionLog{}).Clauses(clause.Returning{}).Create(&txLog)

if result.Error != nil {
return nil, xerrors.Errorf("Failed to insert transaction log: %w - %+v", result.Error, txLog)
}
return txLog, nil
}

type latestBlockNumber struct {
BlockNumber uint64
}

func (s *SqliteBlockStore) GetLatestBlock() (int64, error) {
block := &latestBlockNumber{}

query := `select coalesce(max(number), 0) as block_number from blocks`

result := s.Db.Raw(query).Scan(&block)
if result.Error != nil {
return 0, xerrors.Errorf("Failed to get latest block: %w", result.Error)
}
return int64(block.BlockNumber), nil
}
func (s *SqliteBlockStore) GetBlockByNumber(blockNumber uint64) (*Block, error) {

func (s *SqliteBlockStore) GetBlockByNumber(blockNumber uint64) (*storage.Block, error) {
block := &storage.Block{}

result := s.Db.Model(block).Where("number = ?", blockNumber).First(&block)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return block, nil
}
func (s *SqliteBlockStore) InsertOperatorRestakedStrategies(avsDirectorAddress string, blockNumber uint64, blockTime time.Time, operator string, avs string, strategy string) (*OperatorRestakedStrategies, error) {

}*/
func (s *SqliteBlockStore) InsertOperatorRestakedStrategies(
avsDirectorAddress string,
blockNumber uint64,
blockTime time.Time,
operator string,
avs string,
strategy string,
) (*storage.OperatorRestakedStrategies, error) {
ors := &storage.OperatorRestakedStrategies{
AvsDirectoryAddress: strings.ToLower(avsDirectorAddress),
BlockNumber: blockNumber,
Operator: operator,
Avs: avs,
Strategy: strategy,
BlockTime: blockTime,
}

result := s.Db.Model(&storage.OperatorRestakedStrategies{}).Clauses(clause.Returning{}).Create(&ors)

if result.Error != nil {
return nil, xerrors.Errorf("Failed to insert operator restaked strategies: %w", result.Error)
}
return ors, nil
}

func (s *SqliteBlockStore) GetLatestActiveAvsOperators(blockNumber uint64, avsDirectoryAddress string) ([]*storage.ActiveAvsOperator, error) {
avsDirectoryAddress = strings.ToLower(avsDirectoryAddress)

rows := make([]*storage.ActiveAvsOperator, 0)
query := `
WITH latest_status AS (
SELECT
lower(tl.arguments #>> '{0,Value}') as operator,
lower(tl.arguments #>> '{1,Value}') as avs,
lower(tl.output_data #>> '{status}') as status,
ROW_NUMBER() OVER (PARTITION BY lower(tl.arguments #>> '{0,Value}'), lower(tl.arguments #>> '{1,Value}') ORDER BY block_number DESC) AS row_number
FROM transaction_logs as tl
WHERE
tl.address = ?
AND tl.event_name = 'OperatorAVSRegistrationStatusUpdated'
AND tl.block_number <= ?
)
SELECT avs, operator
FROM latest_status
WHERE row_number = 1 AND status = '1';
`
result := s.Db.Raw(query, avsDirectoryAddress, blockNumber).Scan(&rows)
if result.Error != nil {
return nil, xerrors.Errorf("Failed to get latest active AVS operators: %w", result.Error)
}
return rows, nil
}

0 comments on commit 2ab3318

Please sign in to comment.