/ htlcswitch / held_htlc_set.go
held_htlc_set.go
1 package htlcswitch 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/lightningnetwork/lnd/graph/db/models" 8 ) 9 10 // heldHtlcSet keeps track of outstanding intercepted forwards. It exposes 11 // several methods to manipulate the underlying map structure in a consistent 12 // way. 13 type heldHtlcSet struct { 14 set map[models.CircuitKey]InterceptedForward 15 } 16 17 func newHeldHtlcSet() *heldHtlcSet { 18 return &heldHtlcSet{ 19 set: make(map[models.CircuitKey]InterceptedForward), 20 } 21 } 22 23 // forEach iterates over all held forwards and calls the given callback for each 24 // of them. 25 func (h *heldHtlcSet) forEach(cb func(InterceptedForward)) { 26 for _, fwd := range h.set { 27 cb(fwd) 28 } 29 } 30 31 // popAll calls the callback for each forward and removes them from the set. 32 func (h *heldHtlcSet) popAll(cb func(InterceptedForward)) { 33 for _, fwd := range h.set { 34 cb(fwd) 35 } 36 37 h.set = make(map[models.CircuitKey]InterceptedForward) 38 } 39 40 // popAutoFails calls the callback for each forward that has an auto-fail height 41 // equal or less then the specified pop height and removes them from the set. 42 func (h *heldHtlcSet) popAutoFails(height uint32, cb func(InterceptedForward)) { 43 for key, fwd := range h.set { 44 if uint32(fwd.Packet().AutoFailHeight) > height { 45 continue 46 } 47 48 cb(fwd) 49 50 delete(h.set, key) 51 } 52 } 53 54 // pop returns the specified forward and removes it from the set. 55 func (h *heldHtlcSet) pop(key models.CircuitKey) (InterceptedForward, error) { 56 intercepted, ok := h.set[key] 57 if !ok { 58 return nil, fmt.Errorf("fwd %v not found", key) 59 } 60 61 delete(h.set, key) 62 63 return intercepted, nil 64 } 65 66 // exists tests whether the specified forward is part of the set. 67 func (h *heldHtlcSet) exists(key models.CircuitKey) bool { 68 _, ok := h.set[key] 69 70 return ok 71 } 72 73 // push adds the specified forward to the set. An error is returned if the 74 // forward exists already. 75 func (h *heldHtlcSet) push(key models.CircuitKey, 76 fwd InterceptedForward) error { 77 78 if fwd == nil { 79 return errors.New("nil fwd pushed") 80 } 81 82 if h.exists(key) { 83 return errors.New("htlc already exists in set") 84 } 85 86 h.set[key] = fwd 87 88 return nil 89 }