eventindexer

package
v0.3.1-0...-ee1233d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 15, 2024 License: MIT Imports: 14 Imported by: 0

README

Golang Relayer

Indexer

Catches events, stores them in the database to be queried via API.

Running the app

run cp .default.env .env, and add your own private key as RELAYER_ECDSA_KEY in .env. You need to be running a MySQL instance, and replace all the MYSQL_ env vars with yours.

Run go run cmd/main.go --help to see a list of possible configuration flags, or go run cmd/main.go to run with defaults, which will process messages from L1 to L2, and from L2 to L1, and start indexing blocks from 0.

Block data

  1. parse data
  2. store
  3. cron job that updates every 24 hours

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoEthClient       = errors.Validation.NewWithKeyAndDetail("ERR_NO_ETH_CLIENT", "EthClient is required")
	ErrNoEventRepository = errors.Validation.NewWithKeyAndDetail(
		"ERR_NO_EVENT_REPOSITORY",
		"EventRepository is required",
	)
	ErrNoNFTBalanceRepository = errors.Validation.NewWithKeyAndDetail(
		"ERR_NO_NFT_BALANCE_REPOSITORY",
		"NFTBalanceRepository is required",
	)
	ErrNoStatRepository = errors.Validation.NewWithKeyAndDetail(
		"ERR_NO_STAT_REPOSITORY",
		"StatRepository is required",
	)
	ErrNoBlockRepository = errors.Validation.NewWithKeyAndDetail(
		"ERR_NO_BLOCK_REPOSITORY",
		"BlockRepository is required",
	)
	ErrNoCORSOrigins = errors.Validation.NewWithKeyAndDetail("ERR_NO_CORS_ORIGINS", "CORS Origins are required")
	ErrNoRPCClient   = errors.Validation.NewWithKeyAndDetail("ERR_NO_RPC_CLIENT", "RPCClient is required")
	ErrInvalidMode   = errors.Validation.NewWithKeyAndDetail("ERR_INVALID_MODE", "Mode not supported")
)
View Source
var (
	EventNameTransitionProved    = "TransitionProved"
	EventNameTransitionContested = "TransitionContested"
	EventNameBlockProposed       = "BlockProposed"
	EventNameBlockAssigned       = "BlockAssigned"
	EventNameBlockVerified       = "BlockVerified"
	EventNameMessageSent         = "MessageSent"
	EventNameSwap                = "Swap"
	EventNameMint                = "Mint"
	EventNameNFTTransfer         = "Transfer"
)
View Source
var (
	BlockProposedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_proposed_events_processed_ops_total",
		Help: "The total number of processed BlockProposed events",
	})
	BlockAssignedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_assigned_events_processed_ops_total",
		Help: "The total number of processed BlockAssigned events",
	})
	BlockProposedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_proposed_events_processed_error_ops_total",
		Help: "The total number of processed BlockProposed event errors encountered",
	})
	BlockAssignedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_assigned_events_processed_error_ops_total",
		Help: "The total number of processed BlockAssigned event errors encountered",
	})
	TransitionProvedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_proven_events_processed_ops_total",
		Help: "The total number of processed BlockProven events",
	})
	TransitionProvedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_proven_events_processed_error_ops_total",
		Help: "The total number of processed BlockProven event errors encountered",
	})
	TransitionContestedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_contested_events_processed_ops_total",
		Help: "The total number of processed BlockContested events",
	})
	TransitionContestedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_contested_events_processed_error_ops_total",
		Help: "The total number of processed BlockContested event errors encountered",
	})
	BlockVerifiedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_verified_events_processed_ops_total",
		Help: "The total number of processed BlockVerified events",
	})
	BlockVerifiedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "block_verified_events_processed_error_ops_total",
		Help: "The total number of processed BlockVerified event errors encountered",
	})
	SlashedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "slashed_events_processed_ops_total",
		Help: "The total number of processed Slashed events",
	})
	SlashedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "slashed_events_processed_error_ops_total",
		Help: "The total number of processed Slashed event errors encountered",
	})
	StakedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "staked_events_processed_ops_total",
		Help: "The total number of processed Staked events",
	})
	StakedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "staked_events_processed_error_ops_total",
		Help: "The total number of processed Staked event errors encountered",
	})
	ExitedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "exited_events_processed_ops_total",
		Help: "The total number of processed Exited events",
	})
	ExitedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "exited_events_processed_error_ops_total",
		Help: "The total number of processed Exited event errors encountered",
	})
	WithdrawnEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "withdrawn_events_processed_ops_total",
		Help: "The total number of processed Exited events",
	})
	WithdrawnEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "withdrawn_events_processed_error_ops_total",
		Help: "The total number of processed Exited event errors encountered",
	})
	MessageSentEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "message_sent_events_processed_ops_total",
		Help: "The total number of processed MessageSent events",
	})
	MessageSentEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "message_sent_events_processed_error_ops_total",
		Help: "The total number of processed MessageSent event errors encountered",
	})
	SwapEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "swap_events_processed_ops_total",
		Help: "The total number of processed Swap events",
	})
	SwapEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "swap_events_processed_error_ops_total",
		Help: "The total number of processed Swap event errors encountered",
	})
	LiquidityAddedEventsProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "liquidity_added_events_processed_ops_total",
		Help: "The total number of processed LiquidityAdded events",
	})
	LiquidityAddedEventsProcessedError = promauto.NewCounter(prometheus.CounterOpts{
		Name: "liquidity_added_events_processed_error_ops_total",
		Help: "The total number of processed LiquidityAdded event errors encountered",
	})
	BlocksProcessed = promauto.NewCounter(prometheus.CounterOpts{
		Name: "blocks_processed_ops_total",
		Help: "The total number of processed blocks",
	})
	ErrorsEncounteredDuringSubscription = promauto.NewCounter(prometheus.CounterOpts{
		Name: "errors_encountered_during_subscription_opts_total",
		Help: "The total number of errors that occurred during active subscription",
	})
)
View Source
var (
	StatTypeProofTime   = "proofTime"
	StatTypeProofReward = "proofReward"
)
View Source
var (
	ErrNoDB = errors.Validation.NewWithKeyAndDetail("ERR_NO_DB", "DB is required")
)

Functions

This section is empty.

Types

type Account

type Account struct {
	ID           int       `json:"id"`
	Address      string    `json:"address"`
	TransactedAt time.Time `json:"transactedAt"`
}

type AccountRepository

type AccountRepository interface {
	Save(ctx context.Context, address common.Address, transactedAt time.Time) error
}

type Block

type Block struct {
	ID           int       `json:"id"`
	ChainID      int64     `json:"chainID"`
	BlockID      int64     `json:"blockID"`
	TransactedAt time.Time `json:"transactedAt"`
}

type BlockRepository

type BlockRepository interface {
	Save(ctx context.Context, tx *types.Block, chainID *big.Int) error
}

type Caller

type Caller interface {
	CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
}

type ChartItem

type ChartItem struct {
	Date  string `json:"date"`
	Value string `json:"value"`
}

type ChartRepository

type ChartRepository interface {
	Find(
		ctx context.Context,
		task string,
		start string,
		end string,
		feeTokenAddress string,
		tier string,
	) (*ChartResponse, error)
}

type ChartResponse

type ChartResponse struct {
	Chart []ChartItem `json:"chart"`
}

type DB

type DB interface {
	DB() (*sql.DB, error)
	GormDB() *gorm.DB
}

type DBConnectionOpts

type DBConnectionOpts struct {
	Name     string
	Password string
	Host     string
	Database string
	OpenFunc func(dsn string) (DB, error)
}

type Event

type Event struct {
	ID              int                 `json:"id"`
	Name            string              `json:"name"`
	Data            datatypes.JSON      `json:"data"`
	ChainID         int64               `json:"chainID"`
	Event           string              `json:"event"`
	Address         string              `json:"address"`
	BlockID         sql.NullInt64       `json:"blockID"`
	Amount          decimal.NullDecimal `json:"amount"`
	ProofReward     decimal.NullDecimal `json:"proofReward"`
	ProposerReward  decimal.NullDecimal `json:"proposerReward"`
	AssignedProver  string              `json:"assignedProver"`
	To              string              `json:"to"`
	TokenID         sql.NullInt64       `json:"tokenID"`
	ContractAddress string              `json:"contractAddress"`
	FeeTokenAddress string              `json:"feeTokenAddress"`
	TransactedAt    time.Time           `json:"transactedAt"`
	Tier            sql.NullInt16       `json:"tier"`
}

Event represents a stored EVM event. The fields will be serialized into the Data field to be unmarshalled into a concrete struct dependant on the name of the event

type EventRepository

type EventRepository interface {
	Save(ctx context.Context, opts SaveEventOpts) (*Event, error)
	FindUniqueProvers(
		ctx context.Context,
	) ([]UniqueProversResponse, error)
	FindUniqueProposers(
		ctx context.Context,
	) ([]UniqueProposersResponse, error)
	FindByEventTypeAndBlockID(
		ctx context.Context,
		eventType string,
		blockID int64) (*Event, error)
	Delete(
		ctx context.Context,
		id int,
	) error
	GetCountByAddressAndEventName(ctx context.Context, address string, event string) (int, error)
	GetByAddressAndEventName(
		ctx context.Context,
		req *http.Request,
		address string,
		event string,
	) (paginate.Page, error)
	FirstByAddressAndEventName(
		ctx context.Context,
		address string,
		event string,
	) (*Event, error)
	GetAssignedBlocksByProverAddress(
		ctx context.Context,
		req *http.Request,
		address string,
	) (paginate.Page, error)
}

EventRepository is used to interact with events in the store

type NFTBalance

type NFTBalance struct {
	ID              int    `json:"id"`
	ChainID         int64  `json:"chainID"`
	Address         string `json:"address"`
	Amount          int64  `json:"amount"`
	TokenID         int64  `json:"tokenID"`
	ContractAddress string `json:"contractAddress"`
	ContractType    string `json:"contractType"`
}

NFTBalance represents a single contractAddress/tokenId pairing for a given holder address

type NFTBalanceRepository

type NFTBalanceRepository interface {
	SubtractBalance(ctx context.Context, opts UpdateNFTBalanceOpts) (*NFTBalance, error)
	IncreaseBalance(ctx context.Context, opts UpdateNFTBalanceOpts) (*NFTBalance, error)
	FindByAddress(ctx context.Context,
		req *http.Request,
		address string,
		chainID string,
	) (paginate.Page, error)
}

NFTBalanceRepository is used to interact with nft balances in the store

type ProcessedBlock

type ProcessedBlock struct {
	ID      int    `json:"id"`
	Height  uint64 `json:"blockHeight" gorm:"column:block_height"`
	Hash    string `json:"hash"`
	ChainID int64  `json:"chainID"`
}

ProcessedBlock is a database model representing simple header types to keep track of our most recently processed block number and hash.

type ProcessedBlockRepository

type ProcessedBlockRepository interface {
	Save(opts SaveProcessedBlockOpts) error
	GetLatestBlockProcessed(chainID *big.Int) (*ProcessedBlock, error)
}

ProcessedBlockRepository defines methods necessary for interacting with the block store.

type SaveEventOpts

type SaveEventOpts struct {
	Name            string
	Data            string
	ChainID         *big.Int
	Event           string
	Address         string
	BlockID         *int64
	Amount          *big.Int
	ProposerReward  *big.Int
	ProofReward     *big.Int
	AssignedProver  *string
	To              *string
	TokenID         *int64
	ContractAddress *string
	FeeTokenAddress *string
	TransactedAt    time.Time
	Tier            *uint16
}

SaveEventOpts

type SaveProcessedBlockOpts

type SaveProcessedBlockOpts struct {
	Height  uint64
	Hash    common.Hash
	ChainID *big.Int
}

SaveProcessedBlockOpts is required to store a new block

type SaveStatOpts

type SaveStatOpts struct {
	ProofTime       *big.Int
	ProofReward     *big.Int
	FeeTokenAddress *string
	StatType        string
}

SaveStatOpts

type Stat

type Stat struct {
	ID                 int    `json:"id"`
	AverageProofTime   string `json:"averageProofTime"`
	AverageProofReward string `json:"averageProofReward"`
	NumProofs          uint64 `json:"numProofs"`
	NumBlocksAssigned  uint64 `json:"numBlocksAssigned"`
	FeeTokenAddress    string `json:"feeTokenAddress"`
	StatType           string `json:"statType"`
}

Event represents a stored EVM event. The fields will be serialized into the Data field to be unmarshalled into a concrete struct dependant on the name of the event

type StatRepository

type StatRepository interface {
	Save(ctx context.Context, opts SaveStatOpts) (*Stat, error)
	Find(ctx context.Context, statType string, feeTokenAddress *string) (*Stat, error)
	FindAll(ctx context.Context) ([]*Stat, error)
}

StatRepository is used to interact with stats in the store

type TimeSeriesData

type TimeSeriesData struct {
	ID        int
	Task      string
	Value     decimal.NullDecimal
	Date      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Transaction

type Transaction struct {
	ID              int                 `json:"id"`
	ChainID         int64               `json:"chainID"`
	Sender          string              `json:"sender"`
	Recipient       string              `json:"recipient"`
	BlockID         int64               `json:"blockID"`
	Amount          decimal.NullDecimal `json:"amount"`
	GasPrice        string              `json:"gasPrice"`
	TransactedAt    time.Time           `json:"transactedAt"`
	ContractAddress string              `json:"contractAddress"`
}

type TransactionRepository

type TransactionRepository interface {
	Save(
		ctx context.Context,
		tx *types.Transaction,
		sender common.Address,
		blockID *big.Int,
		timestamp time.Time,
		contractAddress common.Address) error
}

type UniqueProposersResponse

type UniqueProposersResponse struct {
	Address string `json:"address"`
	Count   int    `json:"count"`
}

type UniqueProversResponse

type UniqueProversResponse struct {
	Address string `json:"address"`
	Count   int    `json:"count"`
}

type UpdateNFTBalanceOpts

type UpdateNFTBalanceOpts struct {
	ChainID         int64
	Address         string
	TokenID         int64
	ContractAddress string
	ContractType    string
	Amount          int64
}

Directories

Path Synopsis
cmd
contracts
Code generated by swaggo/swag.
Code generated by swaggo/swag.
pkg
db

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL