github.com/ethereum-optimism/optimism@v1.7.2/op-node/p2p/store/peer_ban_book.go (about) 1 package store 2 3 import ( 4 "context" 5 "encoding/json" 6 "time" 7 8 "github.com/ethereum-optimism/optimism/op-service/clock" 9 "github.com/ethereum/go-ethereum/log" 10 ds "github.com/ipfs/go-datastore" 11 "github.com/libp2p/go-libp2p/core/peer" 12 ) 13 14 const ( 15 peerBanCacheSize = 100 16 peerBanRecordExpiration = time.Hour * 24 * 7 17 ) 18 19 var peerBanExpirationsBase = ds.NewKey("/peers/ban_expiration") 20 21 type peerBanRecord struct { 22 Expiry int64 `json:"expiry"` // unix timestamp in seconds 23 LastUpdate int64 `json:"lastUpdate"` // unix timestamp in seconds 24 } 25 26 func (s *peerBanRecord) SetLastUpdated(t time.Time) { 27 s.LastUpdate = t.Unix() 28 } 29 30 func (s *peerBanRecord) LastUpdated() time.Time { 31 return time.Unix(s.LastUpdate, 0) 32 } 33 34 func (s *peerBanRecord) MarshalBinary() (data []byte, err error) { 35 return json.Marshal(s) 36 } 37 38 func (s *peerBanRecord) UnmarshalBinary(data []byte) error { 39 return json.Unmarshal(data, s) 40 } 41 42 type peerBanUpdate time.Time 43 44 func (p peerBanUpdate) Apply(rec *peerBanRecord) { 45 rec.Expiry = time.Time(p).Unix() 46 } 47 48 type peerBanBook struct { 49 book *recordsBook[peer.ID, *peerBanRecord] 50 } 51 52 func newPeerBanRecord() *peerBanRecord { 53 return new(peerBanRecord) 54 } 55 56 func newPeerBanBook(ctx context.Context, logger log.Logger, clock clock.Clock, store ds.Batching) (*peerBanBook, error) { 57 book, err := newRecordsBook[peer.ID, *peerBanRecord](ctx, logger, clock, store, peerBanCacheSize, peerBanRecordExpiration, peerBanExpirationsBase, newPeerBanRecord, peerIDKey) 58 if err != nil { 59 return nil, err 60 } 61 return &peerBanBook{book: book}, nil 62 } 63 64 func (d *peerBanBook) startGC() { 65 d.book.startGC() 66 } 67 68 func (d *peerBanBook) GetPeerBanExpiration(id peer.ID) (time.Time, error) { 69 rec, err := d.book.getRecord(id) 70 if err == UnknownRecordErr { 71 return time.Time{}, UnknownBanErr 72 } 73 if err != nil { 74 return time.Time{}, err 75 } 76 return time.Unix(rec.Expiry, 0), nil 77 } 78 79 func (d *peerBanBook) SetPeerBanExpiration(id peer.ID, expirationTime time.Time) error { 80 if expirationTime == (time.Time{}) { 81 return d.book.deleteRecord(id) 82 } 83 _, err := d.book.SetRecord(id, peerBanUpdate(expirationTime)) 84 return err 85 } 86 87 func (d *peerBanBook) Close() { 88 d.book.Close() 89 }