smartban.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package smartban
  2. import (
  3. "sync"
  4. g "github.com/anacrolix/generics"
  5. )
  6. type Cache[Peer, BlockKey, Hash comparable] struct {
  7. Hash func([]byte) Hash
  8. lock sync.RWMutex
  9. blocks map[BlockKey][]peerAndHash[Peer, Hash]
  10. }
  11. type Block[Key any] struct {
  12. Key Key
  13. Data []byte
  14. }
  15. type peerAndHash[Peer, Hash any] struct {
  16. Peer Peer
  17. Hash Hash
  18. }
  19. func (me *Cache[Peer, BlockKey, Hash]) Init() {
  20. g.MakeMap(&me.blocks)
  21. }
  22. func (me *Cache[Peer, BlockKey, Hash]) RecordBlock(peer Peer, key BlockKey, data []byte) {
  23. hash := me.Hash(data)
  24. me.lock.Lock()
  25. defer me.lock.Unlock()
  26. peers := me.blocks[key]
  27. peers = append(peers, peerAndHash[Peer, Hash]{peer, hash})
  28. me.blocks[key] = peers
  29. }
  30. func (me *Cache[Peer, BlockKey, Hash]) CheckBlock(key BlockKey, data []byte) (bad []Peer) {
  31. correct := me.Hash(data)
  32. me.lock.RLock()
  33. defer me.lock.RUnlock()
  34. for _, item := range me.blocks[key] {
  35. if item.Hash != correct {
  36. bad = append(bad, item.Peer)
  37. }
  38. }
  39. return
  40. }
  41. func (me *Cache[Peer, BlockKey, Hash]) ForgetBlock(key BlockKey) {
  42. me.lock.Lock()
  43. defer me.lock.Unlock()
  44. delete(me.blocks, key)
  45. }
  46. func (me *Cache[Peer, BlockKey, Hash]) HasBlocks() bool {
  47. me.lock.RLock()
  48. defer me.lock.RUnlock()
  49. return len(me.blocks) != 0
  50. }