github.com/decred/dcrlnd@v0.7.6/channeldb/migration24/migration.go (about) 1 package migration24 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "io" 7 8 mig "github.com/decred/dcrlnd/channeldb/migration_01_to_11" 9 "github.com/decred/dcrlnd/kvdb" 10 ) 11 12 var ( 13 // closedChannelBucket stores summarization information concerning 14 // previously open, but now closed channels. 15 closedChannelBucket = []byte("closed-chan-bucket") 16 17 // fwdPackagesKey is the root-level bucket that all forwarding packages 18 // are written. This bucket is further subdivided based on the short 19 // channel ID of each channel. 20 fwdPackagesKey = []byte("fwd-packages") 21 ) 22 23 // MigrateFwdPkgCleanup deletes all the forwarding packages of closed channels. 24 // It determines the closed channels by iterating closedChannelBucket. The 25 // ShortChanID found in the ChannelCloseSummary is then used as a key to query 26 // the forwarding packages bucket. If a match is found, it will be deleted. 27 func MigrateFwdPkgCleanup(tx kvdb.RwTx) error { 28 log.Infof("Deleting forwarding packages for closed channels") 29 30 // Find all closed channel summaries, which are stored in the 31 // closeBucket. 32 closeBucket := tx.ReadBucket(closedChannelBucket) 33 if closeBucket == nil { 34 return nil 35 } 36 37 var chanSummaries []*mig.ChannelCloseSummary 38 39 // appendSummary is a function closure to help put deserialized close 40 // summeries into chanSummaries. 41 appendSummary := func(_ []byte, summaryBytes []byte) error { 42 summaryReader := bytes.NewReader(summaryBytes) 43 chanSummary, err := deserializeCloseChannelSummary( 44 summaryReader, 45 ) 46 if err != nil { 47 return err 48 } 49 50 // Skip pending channels 51 if chanSummary.IsPending { 52 return nil 53 } 54 55 chanSummaries = append(chanSummaries, chanSummary) 56 return nil 57 } 58 59 if err := closeBucket.ForEach(appendSummary); err != nil { 60 return err 61 } 62 63 // Now we will load the forwarding packages bucket, delete all the 64 // nested buckets whose source matches the ShortChanID found in the 65 // closed channel summeraries. 66 fwdPkgBkt := tx.ReadWriteBucket(fwdPackagesKey) 67 if fwdPkgBkt == nil { 68 return nil 69 } 70 71 // Iterate over all close channels and remove their forwarding packages. 72 for _, summery := range chanSummaries { 73 sourceBytes := makeLogKey(summery.ShortChanID.ToUint64()) 74 75 // First, we will try to find the corresponding bucket. If there 76 // is not a nested bucket matching the ShortChanID, we will skip 77 // it. 78 if fwdPkgBkt.NestedReadBucket(sourceBytes[:]) == nil { 79 continue 80 } 81 82 // Otherwise, wipe all the forwarding packages. 83 if err := fwdPkgBkt.DeleteNestedBucket( 84 sourceBytes[:]); err != nil { 85 86 return err 87 } 88 } 89 90 log.Infof("Deletion of forwarding packages of closed channels " + 91 "complete! DB compaction is recommended to free up the" + 92 "disk space.") 93 return nil 94 } 95 96 // deserializeCloseChannelSummary will decode a CloseChannelSummary with no 97 // optional fields. 98 func deserializeCloseChannelSummary( 99 r io.Reader) (*mig.ChannelCloseSummary, error) { 100 101 c := &mig.ChannelCloseSummary{} 102 err := mig.ReadElements( 103 r, 104 &c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID, 105 &c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance, 106 &c.TimeLockedBalance, &c.CloseType, &c.IsPending, 107 ) 108 if err != nil { 109 return nil, err 110 } 111 return c, nil 112 } 113 114 // makeLogKey converts a uint64 into an 8 byte array. 115 func makeLogKey(updateNum uint64) [8]byte { 116 var key [8]byte 117 binary.BigEndian.PutUint64(key[:], updateNum) 118 return key 119 }