htlcswitch/circuit_map: prune stray locally-initiated keystones
This commit is contained in:
parent
c2055d4a9e
commit
a213810563
@ -225,8 +225,10 @@ func (cm *circuitMap) initBuckets() error {
|
|||||||
|
|
||||||
// restoreMemState loads the contents of the half circuit and full circuit
|
// restoreMemState loads the contents of the half circuit and full circuit
|
||||||
// buckets from disk and reconstructs the in-memory representation of the
|
// buckets from disk and reconstructs the in-memory representation of the
|
||||||
// circuit map. Afterwards, the state of the hash index is reconstructed using
|
// circuit map. Afterwards, the state of the hash index is reconstructed using
|
||||||
// the recovered set of full circuits.
|
// the recovered set of full circuits. This method will also remove any stray
|
||||||
|
// keystones, which are those that appear fully-opened, but have no pending
|
||||||
|
// circuit related to the intended incoming link.
|
||||||
func (cm *circuitMap) restoreMemState() error {
|
func (cm *circuitMap) restoreMemState() error {
|
||||||
log.Infof("Restoring in-memory circuit state from disk")
|
log.Infof("Restoring in-memory circuit state from disk")
|
||||||
|
|
||||||
@ -235,7 +237,7 @@ func (cm *circuitMap) restoreMemState() error {
|
|||||||
pending = make(map[CircuitKey]*PaymentCircuit)
|
pending = make(map[CircuitKey]*PaymentCircuit)
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := cm.cfg.DB.View(func(tx *bolt.Tx) error {
|
if err := cm.cfg.DB.Update(func(tx *bolt.Tx) error {
|
||||||
// Restore any of the circuits persisted in the circuit bucket
|
// Restore any of the circuits persisted in the circuit bucket
|
||||||
// back into memory.
|
// back into memory.
|
||||||
circuitBkt := tx.Bucket(circuitAddKey)
|
circuitBkt := tx.Bucket(circuitAddKey)
|
||||||
@ -264,6 +266,7 @@ func (cm *circuitMap) restoreMemState() error {
|
|||||||
return ErrCorruptedCircuitMap
|
return ErrCorruptedCircuitMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var strayKeystones []Keystone
|
||||||
if err := keystoneBkt.ForEach(func(k, v []byte) error {
|
if err := keystoneBkt.ForEach(func(k, v []byte) error {
|
||||||
var (
|
var (
|
||||||
inKey CircuitKey
|
inKey CircuitKey
|
||||||
@ -280,15 +283,45 @@ func (cm *circuitMap) restoreMemState() error {
|
|||||||
|
|
||||||
// Retrieve the pending circuit, set its keystone, then
|
// Retrieve the pending circuit, set its keystone, then
|
||||||
// add it to the opened map.
|
// add it to the opened map.
|
||||||
circuit := pending[inKey]
|
circuit, ok := pending[inKey]
|
||||||
circuit.Outgoing = outKey
|
if ok {
|
||||||
opened[*outKey] = circuit
|
circuit.Outgoing = outKey
|
||||||
|
opened[*outKey] = circuit
|
||||||
|
} else {
|
||||||
|
strayKeystones = append(strayKeystones, Keystone{
|
||||||
|
InKey: inKey,
|
||||||
|
OutKey: *outKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If any stray keystones were found, we'll proceed to prune
|
||||||
|
// them from the circuit map's persistent storage. This may
|
||||||
|
// manifest on older nodes that had updated channels before
|
||||||
|
// their short channel id was set properly. We believe this
|
||||||
|
// issue has been fixed, though this will allow older nodes to
|
||||||
|
// recover without additional intervention.
|
||||||
|
for _, strayKeystone := range strayKeystones {
|
||||||
|
// As a precaution, we will only cleanup keystones
|
||||||
|
// related to locally-initiated payments. If a
|
||||||
|
// documented case of stray keystones emerges for
|
||||||
|
// forwarded payments, this check should be removed, but
|
||||||
|
// with extreme caution.
|
||||||
|
if strayKeystone.OutKey.ChanID != sourceHop {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Removing stray keystone: %v", strayKeystone)
|
||||||
|
err := keystoneBkt.Delete(strayKeystone.OutKey.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user