From 11c6887ffaf3ffb9621ccf88dd396c780085fb4f Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sun, 9 Dec 2018 19:28:54 -0800 Subject: [PATCH] channeldb: refactor syncPending to expose new syncNewChannel function The new syncNewChannel function will allow callers to insert a new channel given the OpenChannel struct, and set of addresses for the channel peer. This new method will also create a new LinkNode for the peer if one doesn't already exist. --- channeldb/channel.go | 69 +++++++++++++++++++++++++------------------- channeldb/error.go | 5 ++++ 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/channeldb/channel.go b/channeldb/channel.go index e33ae77a..8dd26e57 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -656,16 +656,20 @@ func (c *OpenChannel) fullSync(tx *bbolt.Tx) error { } // With the bucket for the node fetched, we can now go down another - // level, creating the bucket (if it doesn't exist), for this channel - // itself. + // level, creating the bucket for this channel itself. var chanPointBuf bytes.Buffer if err := writeOutpoint(&chanPointBuf, &c.FundingOutpoint); err != nil { return err } - chanBucket, err := chainBucket.CreateBucketIfNotExists( + chanBucket, err := chainBucket.CreateBucket( chanPointBuf.Bytes(), ) - if err != nil { + switch { + case err == bbolt.ErrBucketExists: + // If this channel already exists, then in order to avoid + // overriding it, we'll return an error back up to the caller. + return ErrChanAlreadyExists + case err != nil: return err } @@ -911,35 +915,40 @@ func (c *OpenChannel) SyncPending(addr net.Addr, pendingHeight uint32) error { c.FundingBroadcastHeight = pendingHeight return c.Db.Update(func(tx *bbolt.Tx) error { - // First, sync all the persistent channel state to disk. - if err := c.fullSync(tx); err != nil { - return err - } - - nodeInfoBucket, err := tx.CreateBucketIfNotExists(nodeInfoBucket) - if err != nil { - return err - } - - // If a LinkNode for this identity public key already exists, - // then we can exit early. - nodePub := c.IdentityPub.SerializeCompressed() - if nodeInfoBucket.Get(nodePub) != nil { - return nil - } - - // Next, we need to establish a (possibly) new LinkNode - // relationship for this channel. The LinkNode metadata - // contains reachability, up-time, and service bits related - // information. - linkNode := c.Db.NewLinkNode(wire.MainNet, c.IdentityPub, addr) - - // TODO(roasbeef): do away with link node all together? - - return putLinkNode(nodeInfoBucket, linkNode) + return syncNewChannel(tx, c, []net.Addr{addr}) }) } +// syncNewChannel will write the passed channel to disk, and also create a +// LinkNode (if needed) for the channel peer. +func syncNewChannel(tx *bbolt.Tx, c *OpenChannel, addrs []net.Addr) error { + // First, sync all the persistent channel state to disk. + if err := c.fullSync(tx); err != nil { + return err + } + + nodeInfoBucket, err := tx.CreateBucketIfNotExists(nodeInfoBucket) + if err != nil { + return err + } + + // If a LinkNode for this identity public key already exists, + // then we can exit early. + nodePub := c.IdentityPub.SerializeCompressed() + if nodeInfoBucket.Get(nodePub) != nil { + return nil + } + + // Next, we need to establish a (possibly) new LinkNode relationship + // for this channel. The LinkNode metadata contains reachability, + // up-time, and service bits related information. + linkNode := c.Db.NewLinkNode(wire.MainNet, c.IdentityPub, addrs...) + + // TODO(roasbeef): do away with link node all together? + + return putLinkNode(nodeInfoBucket, linkNode) +} + // UpdateCommitment updates the commitment state for the specified party // (remote or local). The commitment stat completely describes the balance // state at this point in the commitment chain. This method its to be called on diff --git a/channeldb/error.go b/channeldb/error.go index c9ddfb49..c0548106 100644 --- a/channeldb/error.go +++ b/channeldb/error.go @@ -103,6 +103,11 @@ var ( // indicate it should be. ErrEdgePolicyOptionalFieldNotFound = fmt.Errorf("optional field not " + "present") + + // ErrChanAlreadyExists is return when the caller attempts to create a + // channel with a channel point that is already present in the + // database. + ErrChanAlreadyExists = fmt.Errorf("channel already exists") ) // ErrTooManyExtraOpaqueBytes creates an error which should be returned if the