diff --git a/database/database.go b/database/database.go index b1410179..d432b469 100644 --- a/database/database.go +++ b/database/database.go @@ -3,12 +3,20 @@ package database -import "github.com/ava-labs/avalanchego/ids" +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/pkg/errors" +) const ( LatestSeenBlockKey = "latestSeenBlock" ) +var ( + ErrKeyNotFound = errors.New("key not found") + ErrChainNotFound = errors.New("no database for chain") +) + // RelayerDatabase is a key-value store for relayer state, with each chainID maintaining its own state type RelayerDatabase interface { Get(chainID ids.ID, key []byte) ([]byte, error) diff --git a/database/json_file_storage.go b/database/json_file_storage.go index 63e5c6bb..73197208 100644 --- a/database/json_file_storage.go +++ b/database/json_file_storage.go @@ -67,7 +67,7 @@ func NewJSONFileStorage(logger logging.Logger, dir string, networks []ids.ID) (* func (s *JSONFileStorage) Get(chainID ids.ID, key []byte) ([]byte, error) { mutex, ok := s.mutexes[chainID] if !ok { - return nil, errors.New("network does not exist") + return nil, errors.New("database not configured for chain") } mutex.RLock() @@ -83,14 +83,14 @@ func (s *JSONFileStorage) Get(chainID ids.ID, key []byte) ([]byte, error) { return nil, err } if !fileExists { - return nil, errors.Errorf("file does not exist. chainID: %s", chainID) + return nil, ErrChainNotFound } if val, ok := currentState[string(key)]; ok { return []byte(val), nil } - return nil, errors.Errorf("key does not exist. chainID: %s key: %s", chainID, key) + return nil, ErrKeyNotFound } // Put the value into the json database. Read the current chain state and overwrite the key, if it exists diff --git a/relayer/relayer.go b/relayer/relayer.go index 31449d5d..4be40273 100644 --- a/relayer/relayer.go +++ b/relayer/relayer.go @@ -4,6 +4,7 @@ package relayer import ( + "errors" "math/big" "math/rand" "sync" @@ -124,8 +125,16 @@ func NewRelayer( return nil, nil, err } - // Get the latest processed block height from the database. + // Get the latest processed block height from the database. If the database doesn't have a value for the latest block height, + // for this chain, return here without an error. This will cause the subscriber to begin processing new incoming warp messages. latestSeenBlockData, err := r.db.Get(r.sourceChainID, []byte(database.LatestSeenBlockKey)) + if errors.Is(err, database.ErrChainNotFound) { + logger.Info( + "Latest seen block not found in database. Starting from latest block.", + zap.String("chainID", r.sourceChainID.String()), + ) + return &r, sub, nil + } if err != nil { r.logger.Warn("failed to get latest block from database", zap.Error(err)) return nil, nil, err