package db import ( "context" "time" "gorm.io/gorm" ) // ChainListenerDB is the interface for the chain listener database. type ChainListenerDB interface { // PutLatestBlock upserts the latest block on a given chain id to be new height. PutLatestBlock(ctx context.Context, chainID, height uint64) error // LatestBlockForChain gets the latest block for a given chain id. // will return ErrNoLatestBlockForChainID if no block exists for the chain. LatestBlockForChain(ctx context.Context, chainID uint64) (uint64, error) // SetListenerName sets the listener name. SetListenerName(name string) } // LastIndexed is used to make sure we haven't missed any events while offline. // since we event source - rather than use a state machine this is needed to make sure we haven't missed any events // by allowing us to go back and source any events we may have missed. // // this does not inherit from gorm.model to allow us to use ChainID as a primary key. type LastIndexed struct { // CreatedAt is the creation time CreatedAt time.Time // UpdatedAt is the update time UpdatedAt time.Time // DeletedAt time DeletedAt gorm.DeletedAt `gorm:"index"` // ChainID is the chain id of the chain we're watching blocks on. This is our primary index. ChainID uint64 `gorm:"column:chain_id;index:idx_chain_name,unique"` // BlockHeight is the highest height we've seen on the chain BlockNumber int `gorm:"block_number"` // ListenerName is the name of the listener that is tracking this chain ListenerName string `gorm:"column:listener_name;index:idx_chain_name,unique"` } // GetAllModels gets all models to migrate // see: https://medium.com/@SaifAbid/slice-interfaces-8c78f8b6345d for an explanation of why we can't do this at initialization time func GetAllModels() (allModels []interface{}) { allModels = []interface{}{&LastIndexed{}} return allModels }