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  }