github.com/ethereum-optimism/optimism@v1.7.2/op-node/p2p/store/ip_ban_book.go (about)

     1  package store
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net"
     7  	"time"
     8  
     9  	"github.com/ethereum-optimism/optimism/op-service/clock"
    10  	"github.com/ethereum/go-ethereum/log"
    11  	ds "github.com/ipfs/go-datastore"
    12  )
    13  
    14  const (
    15  	ipBanCacheSize        = 100
    16  	ipBanRecordExpiration = time.Hour * 24 * 7
    17  )
    18  
    19  var ipBanExpirationsBase = ds.NewKey("/ips/ban_expiration")
    20  
    21  type ipBanRecord struct {
    22  	Expiry     int64 `json:"expiry"`     // unix timestamp in seconds
    23  	LastUpdate int64 `json:"lastUpdate"` // unix timestamp in seconds
    24  }
    25  
    26  func (s *ipBanRecord) SetLastUpdated(t time.Time) {
    27  	s.LastUpdate = t.Unix()
    28  }
    29  
    30  func (s *ipBanRecord) LastUpdated() time.Time {
    31  	return time.Unix(s.LastUpdate, 0)
    32  }
    33  
    34  func (s *ipBanRecord) MarshalBinary() (data []byte, err error) {
    35  	return json.Marshal(s)
    36  }
    37  
    38  func (s *ipBanRecord) UnmarshalBinary(data []byte) error {
    39  	return json.Unmarshal(data, s)
    40  }
    41  
    42  type ipBanUpdate time.Time
    43  
    44  func (p ipBanUpdate) Apply(rec *ipBanRecord) {
    45  	rec.Expiry = time.Time(p).Unix()
    46  }
    47  
    48  type ipBanBook struct {
    49  	book *recordsBook[string, *ipBanRecord]
    50  }
    51  
    52  func newIPBanRecord() *ipBanRecord {
    53  	return new(ipBanRecord)
    54  }
    55  
    56  func ipKey(ip string) ds.Key {
    57  	return ds.NewKey(ip)
    58  }
    59  
    60  func newIPBanBook(ctx context.Context, logger log.Logger, clock clock.Clock, store ds.Batching) (*ipBanBook, error) {
    61  	book, err := newRecordsBook[string, *ipBanRecord](ctx, logger, clock, store, ipBanCacheSize, ipBanRecordExpiration, ipBanExpirationsBase, newIPBanRecord, ipKey)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return &ipBanBook{book: book}, nil
    66  }
    67  
    68  func (d *ipBanBook) startGC() {
    69  	d.book.startGC()
    70  }
    71  
    72  func (d *ipBanBook) GetIPBanExpiration(ip net.IP) (time.Time, error) {
    73  	rec, err := d.book.getRecord(ip.To16().String())
    74  	if err == UnknownRecordErr {
    75  		return time.Time{}, UnknownBanErr
    76  	}
    77  	if err != nil {
    78  		return time.Time{}, err
    79  	}
    80  	return time.Unix(rec.Expiry, 0), nil
    81  }
    82  
    83  func (d *ipBanBook) SetIPBanExpiration(ip net.IP, expirationTime time.Time) error {
    84  	if expirationTime == (time.Time{}) {
    85  		return d.book.deleteRecord(ip.To16().String())
    86  	}
    87  	_, err := d.book.SetRecord(ip.To16().String(), ipBanUpdate(expirationTime))
    88  	return err
    89  }
    90  
    91  func (d *ipBanBook) Close() {
    92  	d.book.Close()
    93  }