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 }