Repository: lightningnetwork/lnd
Pull request #8425 (2024-01-25 04:52:06)

[EZ Review]: avoid leaking pointers to authoritative ChannelPoint
## Change Description
This change has a number of changes to change the way we handle OutPoint's from pointers to values. At a minimum, returning addresses inside of the `channeldb.OpenChannel` is dangerous because that is the source of truth for channel state. On top of that I changed the channel id constructor to take a value as well. That commit is less important but I included it anyway as I don't think we should be using pointers unless we have a really good reason to.

## Steps to Test
CI should handle it

## Pull Request Checklist
### Testing
- [x] Your PR passes all CI checks.
- [x] Tests covering the positive and negative (error paths) are included.
- [x] Bug fixes contain tests triggering the bug to prevent regressions.

### Code Style and Documentation
- [x] The change obeys the [Code Documentation and Commenting](https://github.com/lightningnetwork/lnd/blob/master/docs/code_contribution_guidelines.md#CodeDocumentation) guidelines, and lines wrap at 80.
- [x] Commits follow the [Ideal Git Commit Structure](https://github.com/lightningnetwork/lnd/blob/master/docs/code_contribution_guidelines.md#IdealGitCommitStructure).
- [x] Any new logging statements use an appropriate subsystem and logging level.
- [x] Any new lncli commands have appropriate tags in the comments for the rpc in the proto file.
- [x]  [There is a change description in the release notes](https://github.com/lightningnetwork/lnd/tree/master/docs/release-notes), or `[skip ci]` in the commit message for small changes.

📝 Please see our  [Contribution Guidelines](https://github.com/lightningnetwork/lnd/blob/master/docs/code_contribution_guidelines.md) for further guidance.


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Transitioned from pointer to value usage for `ChanPoint` and `FundingOutpoint` across various files, enhancing consistency and efficiency.
  - Standardized the creation of channel IDs by directly passing `wire.OutPoint` or dereferencing it as needed, improving channel identification logic.

- **Bug Fixes**
  - Resolved channel identification issues to ensure accurate retrieval and management of channel information.

- **Tests**
  - Updated test cases to reflect the revised handling of channel points and identifiers, maintaining the reliability and correctness of tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

coderabbitai[bot]: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: summarize review in progress by coderabbit.ai -->

> [!NOTE]
> Currently processing new changes in this PR. This may take a few minutes, please wait...
> 
> <details>
> <summary>Commits</summary>
> Files that changed from the base of the PR and between 758ae6fbecfca6809bf6d51427717245c3c777db and 206e1aaf090ebfb0d71e1f96bf0f7b55076a83dd.
> </details>
> 
> 
> <details>
> <summary>Files selected for processing (3)</summary>
> 
> * contractcourt/breacharbiter_test.go (18 hunks)
> * lnwallet/channel.go (3 hunks)
> * lnwallet/transactions_test.go (1 hunks)
> 
> </details>
> 
> 

<!-- end of auto-generated comment: summarize review in progress by coderabbit.ai --><!-- tweet_start -->

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

<details>
<summary>Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<!-- tweet_end --><!-- tips_start -->

---

<details>
<summary>Tips</summary>

### Chat

There are 3 ways to chat with CodeRabbit:

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
	- `I pushed a fix in commit <commit_id>.`
	- `Generate unit-tests for this file.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
	- `@coderabbitai generate unit tests for this file.`
	-	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
	- `@coderabbitai generate interesting stats about this repository from git and render them as a table.`
	- `@coderabbitai show all the console.log statements in this repository.`
	- `@coderabbitai read src/utils.ts and generate unit tests.`
	- `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (invoked as PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger a review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai help` to get help.


Additionally, you can add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.

### CodeRabbit Configration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- The JSON schema for the configuration file is available [here](https://coderabbit.ai/integrations/coderabbit-overrides.v2.json).
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json`

### CodeRabbit Discord Community

Join our [Discord Community](https://discord.com/invite/GsXnASn26c) to get help, request features, and share feedback.

</details>

<!-- tips_end -->
lightninglabs-deploy: @proofofkeags, remember to re-request review from reviewers when ready
lightninglabs-deploy: @yyforyongyu: review reminder
@crypt-iq: review reminder
@roasbeef: review reminder
@proofofkeags, remember to re-request review from reviewers when ready
lightninglabs-deploy: @yyforyongyu: review reminder
@crypt-iq: review reminder
@roasbeef: review reminder
@proofofkeags, remember to re-request review from reviewers when ready
lightninglabs-deploy: @yyforyongyu: review reminder
@crypt-iq: review reminder
@roasbeef: review reminder
@proofofkeags, remember to re-request review from reviewers when ready
lightninglabs-deploy: @yyforyongyu: review reminder
@crypt-iq: review reminder
@roasbeef: review reminder
@proofofkeags, remember to re-request review from reviewers when ready

Patch:
diff --git a/.github/CODEOWNERS-HINT b/.github/CODEOWNERS
similarity index 100%
rename from .github/CODEOWNERS-HINT
rename to .github/CODEOWNERS
diff --git a/channeldb/channel.go b/channeldb/channel.go
index 1a07ed91d..7292fd6b0 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -1169,7 +1169,7 @@ func (c *OpenChannel) fullSync(tx kvdb.RwTx) error {
 		return ErrChanAlreadyExists
 	}
 
-	cid := lnwire.NewChanIDFromOutPoint(&c.FundingOutpoint)
+	cid := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
 	if cidBucket.Get(cid[:]) != nil {
 		return ErrChanAlreadyExists
 	}
@@ -1574,7 +1574,7 @@ func (c *OpenChannel) ChanSyncMsg() (*lnwire.ChannelReestablish, error) {
 
 	return &lnwire.ChannelReestablish{
 		ChanID: lnwire.NewChanIDFromOutPoint(
-			&c.FundingOutpoint,
+			c.FundingOutpoint,
 		),
 		NextLocalCommitHeight:  nextLocalCommitHeight,
 		RemoteCommitTailHeight: remoteChainTipHeight,
diff --git a/channeldb/db.go b/channeldb/db.go
index aff70d462..34d621a68 100644
--- a/channeldb/db.go
+++ b/channeldb/db.go
@@ -704,7 +704,7 @@ func (c *ChannelStateDB) FetchChannelByID(tx kvdb.RTx, id lnwire.ChannelID) (
 				return err
 			}
 
-			chanID := lnwire.NewChanIDFromOutPoint(&outPoint)
+			chanID := lnwire.NewChanIDFromOutPoint(outPoint)
 			if chanID != id {
 				return nil
 			}
diff --git a/discovery/gossiper.go b/discovery/gossiper.go
index 2c353bf6a..e1884445e 100644
--- a/discovery/gossiper.go
+++ b/discovery/gossiper.go
@@ -1748,8 +1748,9 @@ func (d *AuthenticatedGossiper) processChanPolicyUpdate(
 			// update with the peer's alias. We do this after
 			// updateChannel so that the alias isn't persisted to
 			// the database.
-			op := &edgeInfo.Info.ChannelPoint
-			chanID := lnwire.NewChanIDFromOutPoint(op)
+			chanID := lnwire.NewChanIDFromOutPoint(
+				edgeInfo.Info.ChannelPoint,
+			)
 
 			var defaultAlias lnwire.ShortChannelID
 			foundAlias, _ := d.cfg.GetAlias(chanID)
diff --git a/fn/go.mod b/fn/go.mod
index e14cb555a..4d1528efe 100644
--- a/fn/go.mod
+++ b/fn/go.mod
@@ -4,12 +4,5 @@ go 1.19
 
 require (
 	github.com/lightninglabs/neutrino/cache v1.1.2
-	github.com/stretchr/testify v1.8.1
 	golang.org/x/exp v0.0.0-20231226003508-02704c960a9b
 )
-
-require (
-	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
-)
diff --git a/fn/go.sum b/fn/go.sum
index 73345fe5e..d066b9820 100644
--- a/fn/go.sum
+++ b/fn/go.sum
@@ -1,21 +1,8 @@
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g=
 github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
 golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/fn/slice.go b/fn/slice.go
deleted file mode 100644
index fe821bff7..000000000
--- a/fn/slice.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package fn
-
-// All returns true when the supplied predicate evaluates to true for all of
-// the values in the slice.
-func All[A any](pred func(A) bool, s []A) bool {
-	for _, val := range s {
-		if !pred(val) {
-			return false
-		}
-	}
-
-	return true
-}
-
-// Any returns true when the supplied predicate evaluates to true for any of
-// the values in the slice.
-func Any[A any](pred func(A) bool, s []A) bool {
-	for _, val := range s {
-		if pred(val) {
-			return true
-		}
-	}
-
-	return false
-}
-
-// Map applies the function argument to all members of the slice and returns a
-// slice of those return values.
-func Map[A, B any](f func(A) B, s []A) []B {
-	res := make([]B, 0, len(s))
-
-	for _, val := range s {
-		res = append(res, f(val))
-	}
-
-	return res
-}
-
-// Filter creates a new slice of values where all the members of the returned
-// slice pass the predicate that is supplied in the argument.
-func Filter[A any](pred func(A) bool, s []A) []A {
-	res := make([]A, 0)
-
-	for _, val := range s {
-		if pred(val) {
-			res = append(res, val)
-		}
-	}
-
-	return res
-}
-
-// Foldl iterates through all members of the slice left to right and reduces
-// them pairwise with an accumulator value that is seeded with the seed value in
-// the argument.
-func Foldl[A, B any](f func(B, A) B, seed B, s []A) B {
-	acc := seed
-
-	for _, val := range s {
-		acc = f(acc, val)
-	}
-
-	return acc
-}
-
-// Foldr, is exactly like Foldl except that it iterates over the slice from
-// right to left.
-func Foldr[A, B any](f func(A, B) B, seed B, s []A) B {
-	acc := seed
-
-	for i := range s {
-		acc = f(s[len(s)-1-i], acc)
-	}
-
-	return acc
-}
-
-// Find returns the first value that passes the supplied predicate, or None if
-// the value wasn't found.
-func Find[A any](pred func(A) bool, s []A) Option[A] {
-	for _, val := range s {
-		if pred(val) {
-			return Some(val)
-		}
-	}
-
-	return None[A]()
-}
-
-// Flatten takes a slice of slices and returns a concatenation of those slices.
-func Flatten[A any](s [][]A) []A {
-	sz := Foldr(
-		func(l []A, acc uint64) uint64 {
-			return uint64(len(l)) + acc
-		}, 0, s,
-	)
-
-	res := make([]A, 0, sz)
-
-	for _, val := range s {
-		res = append(res, val...)
-	}
-
-	return res
-}
-
-// Replicate generates a slice of values initialized by the prototype value.
-func Replicate[A any](n uint, val A) []A {
-	res := make([]A, n)
-
-	for i := range res {
-		res[i] = val
-	}
-
-	return res
-}
-
-// Span, applied to a predicate and a slice, returns two slices where the first
-// element is the longest prefix (possibly empty) of slice elements that
-// satisfy the predicate and second element is the remainder of the slice.
-func Span[A any](pred func(A) bool, s []A) ([]A, []A) {
-	for i := range s {
-		if !pred(s[i]) {
-			fst := make([]A, i)
-			snd := make([]A, len(s)-i)
-
-			copy(fst, s[:i])
-			copy(snd, s[i:])
-
-			return fst, snd
-		}
-	}
-
-	res := make([]A, len(s))
-	copy(res, s)
-
-	return res, []A{}
-}
-
-// SplitAt(n, s) returns a tuple where first element is s prefix of length n
-// and second element is the remainder of the list.
-func SplitAt[A any](n uint, s []A) ([]A, []A) {
-	fst := make([]A, n)
-	snd := make([]A, len(s)-int(n))
-
-	copy(fst, s[:n])
-	copy(snd, s[n:])
-
-	return fst, snd
-}
-
-// ZipWith combines slice elements with the same index using the function
-// argument, returning a slice of the results.
-func ZipWith[A, B, C any](f func(A, B) C, a []A, b []B) []C {
-	var l uint
-
-	if la, lb := len(a), len(b); la < lb {
-		l = uint(la)
-	} else {
-		l = uint(lb)
-	}
-
-	res := make([]C, l)
-
-	for i := 0; i < int(l); i++ {
-		res[i] = f(a[i], b[i])
-	}
-
-	return res
-}
diff --git a/funding/manager.go b/funding/manager.go
index 5196090b7..86e70c17c 100644
--- a/funding/manager.go
+++ b/funding/manager.go
@@ -698,7 +698,7 @@ func (f *Manager) start() error {
 	}
 
 	for _, channel := range allChannels {
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 
 		// For any channels that were in a pending state when the
 		// daemon was last connected, the Funding Manager will
@@ -1113,7 +1113,7 @@ func (f *Manager) stateStep(channel *channeldb.OpenChannel,
 	channelState channelOpeningState,
 	updateChan chan<- *lnrpc.OpenStatusUpdate) error {
 
-	chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 	log.Debugf("Channel(%v) with ShortChanID %v has opening state %v",
 		chanID, shortChanID, channelState)
 
@@ -1273,7 +1273,7 @@ func (f *Manager) advancePendingChannelState(
 
 		// Find and close the discoverySignal for this channel such
 		// that ChannelReady messages will be processed.
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 		discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
 		if ok {
 			close(discoverySignal)
@@ -1339,7 +1339,7 @@ func (f *Manager) advancePendingChannelState(
 	}
 
 	// Success, funding transaction was confirmed.
-	chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 	log.Debugf("ChannelID(%v) is now fully confirmed! "+
 		"(shortChanID=%v)", chanID, confChannel.shortChanID)
 
@@ -2246,7 +2246,7 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
 	// properly synchronize with the writeHandler goroutine, we add a new
 	// channel to the barriers map which will be closed once the channel is
 	// fully open.
-	channelID := lnwire.NewChanIDFromOutPoint(outPoint)
+	channelID := lnwire.NewChanIDFromOutPoint(*outPoint)
 	log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
 
 	// The next message that advances the funding flow will reference the
@@ -2421,7 +2421,7 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
 	// properly synchronize with the writeHandler goroutine, we add a new
 	// channel to the barriers map which will be closed once the channel is
 	// fully open.
-	channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
+	channelID := lnwire.NewChanIDFromOutPoint(fundingOut)
 	log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
 
 	fundingSigned := &lnwire.FundingSigned{}
@@ -2582,7 +2582,7 @@ func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
 	// process the channel confirmation fully before we receive a
 	// channel_ready message.
 	fundingPoint := resCtx.reservation.FundingOutpoint()
-	permChanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
+	permChanID := lnwire.NewChanIDFromOutPoint(*fundingPoint)
 	f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
 
 	// We have to store the forwardingPolicy before the reservation context
@@ -2788,7 +2788,7 @@ func (f *Manager) fundingTimeout(c *channeldb.OpenChannel,
 
 		// Create channel identifier and set the channel ID.
 		cid := newChanIdentifier(pendingID)
-		cid.setChanID(lnwire.NewChanIDFromOutPoint(&c.FundingOutpoint))
+		cid.setChanID(lnwire.NewChanIDFromOutPoint(c.FundingOutpoint))
 
 		// TODO(halseth): should this send be made
 		// reliable?
@@ -2953,7 +2953,7 @@ func (f *Manager) waitForFundingConfirmation(
 
 	fundingPoint := completeChan.FundingOutpoint
 	log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
-		fundingPoint, lnwire.NewChanIDFromOutPoint(&fundingPoint))
+		fundingPoint, lnwire.NewChanIDFromOutPoint(fundingPoint))
 
 	// With the block height and the transaction index known, we can
 	// construct the compact chanID which is used on the network to unique
@@ -3071,7 +3071,7 @@ func (f *Manager) handleFundingConfirmation(
 	confChannel *confirmedChannel) error {
 
 	fundingPoint := completeChan.FundingOutpoint
-	chanID := lnwire.NewChanIDFromOutPoint(&fundingPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
 
 	// TODO(roasbeef): ideally persistent state update for chan above
 	// should be abstracted
@@ -3147,7 +3147,7 @@ func (f *Manager) handleFundingConfirmation(
 func (f *Manager) sendChannelReady(completeChan *channeldb.OpenChannel,
 	channel *lnwallet.LightningChannel) error {
 
-	chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
 
 	var peerKey [33]byte
 	copy(peerKey[:], completeChan.IdentityPub.SerializeCompressed())
@@ -3374,7 +3374,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel,
 	peerAlias *lnwire.ShortChannelID,
 	ourPolicy *models.ChannelEdgePolicy) error {
 
-	chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(completeChan.FundingOutpoint)
 
 	fwdMinHTLC, fwdMaxHTLC := f.extractAnnounceParams(completeChan)
 
@@ -3465,7 +3465,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
 		}
 
 		chanID := lnwire.NewChanIDFromOutPoint(
-			&completeChan.FundingOutpoint,
+			completeChan.FundingOutpoint,
 		)
 		pubKey := peer.PubKey()
 		log.Debugf("Sending our NodeAnnouncement for "+
@@ -3530,7 +3530,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
 		}
 
 		fundingPoint := completeChan.FundingOutpoint
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingPoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
 
 		log.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
 			&fundingPoint, shortChanID)
@@ -3964,7 +3964,7 @@ func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
 	scid *lnwire.ShortChannelID, pendingChanID [32]byte,
 	updateChan chan<- *lnrpc.OpenStatusUpdate) error {
 
-	chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 
 	// Since we've sent+received funding locked at this point, we
 	// can clean up the pending musig2 nonce state.
@@ -3981,7 +3981,7 @@ func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel,
 		// we'll just return, letting the next iteration of the loop
 		// check again.
 		var defaultAlias lnwire.ShortChannelID
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 		foundAlias, _ := f.cfg.AliasManager.GetPeerAlias(chanID)
 		if foundAlias == defaultAlias {
 			return nil
@@ -4876,7 +4876,7 @@ func (f *Manager) pruneZombieReservations() {
 		log.Warnf(err.Error())
 
 		chanID := lnwire.NewChanIDFromOutPoint(
-			resCtx.reservation.FundingOutpoint(),
+			*resCtx.reservation.FundingOutpoint(),
 		)
 
 		// Create channel identifier and set the channel ID.
diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go
index ac3e10bab..efaf28fa3 100644
--- a/htlcswitch/interfaces.go
+++ b/htlcswitch/interfaces.go
@@ -221,7 +221,7 @@ type ChannelLink interface {
 	IsUnadvertised() bool
 
 	// ChannelPoint returns the channel outpoint for the channel link.
-	ChannelPoint() *wire.OutPoint
+	ChannelPoint() wire.OutPoint
 
 	// ShortChanID returns the short channel ID for the channel link. The
 	// short channel ID encodes the exact location in the main chain that
diff --git a/htlcswitch/link.go b/htlcswitch/link.go
index 0b1a3b160..e80c7650c 100644
--- a/htlcswitch/link.go
+++ b/htlcswitch/link.go
@@ -1090,8 +1090,8 @@ func (l *channelLink) htlcManager() {
 	// ActiveLinkEvent. We'll also defer an inactive link notification for
 	// when the link exits to ensure that every active notification is
 	// matched by an inactive one.
-	l.cfg.NotifyActiveLink(*l.ChannelPoint())
-	defer l.cfg.NotifyInactiveLinkEvent(*l.ChannelPoint())
+	l.cfg.NotifyActiveLink(l.ChannelPoint())
+	defer l.cfg.NotifyInactiveLinkEvent(l.ChannelPoint())
 
 	// TODO(roasbeef): need to call wipe chan whenever D/C?
 
@@ -1215,8 +1215,8 @@ func (l *channelLink) htlcManager() {
 	// we can go ahead and send the active channel notification. We'll also
 	// defer the inactive notification for when the link exits to ensure
 	// that every active notification is matched by an inactive one.
-	l.cfg.NotifyActiveChannel(*l.ChannelPoint())
-	defer l.cfg.NotifyInactiveChannel(*l.ChannelPoint())
+	l.cfg.NotifyActiveChannel(l.ChannelPoint())
+	defer l.cfg.NotifyInactiveChannel(l.ChannelPoint())
 
 	// With the channel states synced, we now reset the mailbox to ensure
 	// we start processing all unacked packets in order. This is done here
@@ -1371,7 +1371,7 @@ func (l *channelLink) htlcManager() {
 			// TODO(roasbeef): remove all together
 			go func() {
 				chanPoint := l.channel.ChannelPoint()
-				l.cfg.Peer.WipeChannel(chanPoint)
+				l.cfg.Peer.WipeChannel(&chanPoint)
 			}()
 
 			return
@@ -2558,7 +2558,7 @@ func (l *channelLink) PeerPubKey() [33]byte {
 
 // ChannelPoint returns the channel outpoint for the channel link.
 // NOTE: Part of the ChannelLink interface.
-func (l *channelLink) ChannelPoint() *wire.OutPoint {
+func (l *channelLink) ChannelPoint() wire.OutPoint {
 	return l.channel.ChannelPoint()
 }
 
diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go
index e995b3ed7..6770c949f 100644
--- a/htlcswitch/mock.go
+++ b/htlcswitch/mock.go
@@ -907,7 +907,10 @@ func (f *mockChannelLink) PeerPubKey() [33]byte {
 	return f.peer.PubKey()
 }
 
-func (f *mockChannelLink) ChannelPoint() *wire.OutPoint                 { return &wire.OutPoint{} }
+func (f *mockChannelLink) ChannelPoint() wire.OutPoint {
+	return wire.OutPoint{}
+}
+
 func (f *mockChannelLink) Stop()                                        {}
 func (f *mockChannelLink) EligibleToForward() bool                      { return f.eligible }
 func (f *mockChannelLink) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go
index 0e2101027..a0714a2c3 100644
--- a/htlcswitch/switch.go
+++ b/htlcswitch/switch.go
@@ -621,7 +621,7 @@ func (s *Switch) UpdateForwardingPolicies(
 
 	// Update each link in chanPolicies.
 	for targetLink, policy := range chanPolicies {
-		cid := lnwire.NewChanIDFromOutPoint(&targetLink)
+		cid := lnwire.NewChanIDFromOutPoint(targetLink)
 
 		link, ok := s.linkIndex[cid]
 		if !ok {
@@ -1797,7 +1797,7 @@ out:
 		// relevant link (if it exists) so the channel can be
 		// cooperatively closed (if possible).
 		case req := <-s.chanCloseRequests:
-			chanID := lnwire.NewChanIDFromOutPoint(req.ChanPoint)
+			chanID := lnwire.NewChanIDFromOutPoint(*req.ChanPoint)
 
 			s.indexMtx.RLock()
 			link, ok := s.linkIndex[chanID]
diff --git a/lnrpc/invoicesrpc/addinvoice.go b/lnrpc/invoicesrpc/addinvoice.go
index 8b38b76a2..3e20ebf62 100644
--- a/lnrpc/invoicesrpc/addinvoice.go
+++ b/lnrpc/invoicesrpc/addinvoice.go
@@ -731,7 +731,7 @@ func shouldIncludeChannel(cfg *SelectHopHintsCfg,
 	}
 
 	chanID := lnwire.NewChanIDFromOutPoint(
-		&channel.FundingOutpoint,
+		channel.FundingOutpoint,
 	)
 
 	hopHintInfo := newHopHintInfo(channel, cfg.IsChannelActive(chanID))
diff --git a/lnwallet/chancloser/chancloser.go b/lnwallet/chancloser/chancloser.go
index b77e175e6..bc9a1c903 100644
--- a/lnwallet/chancloser/chancloser.go
+++ b/lnwallet/chancloser/chancloser.go
@@ -268,11 +268,12 @@ func NewChanCloser(cfg ChanCloseCfg, deliveryScript []byte,
 	idealFeePerKw chainfee.SatPerKWeight, negotiationHeight uint32,
 	closeReq *htlcswitch.ChanClose, locallyInitiated bool) *ChanCloser {
 
-	cid := lnwire.NewChanIDFromOutPoint(cfg.Channel.ChannelPoint())
+	chanPoint := cfg.Channel.ChannelPoint()
+	cid := lnwire.NewChanIDFromOutPoint(chanPoint)
 	return &ChanCloser{
 		closeReq:            closeReq,
 		state:               closeIdle,
-		chanPoint:           *cfg.Channel.ChannelPoint(),
+		chanPoint:           chanPoint,
 		cid:                 cid,
 		cfg:                 cfg,
 		negotiationHeight:   negotiationHeight,
diff --git a/lnwallet/chancloser/interface.go b/lnwallet/chancloser/interface.go
index 4daf5ac34..40b81efb4 100644
--- a/lnwallet/chancloser/interface.go
+++ b/lnwallet/chancloser/interface.go
@@ -29,7 +29,7 @@ type CoopFeeEstimator interface {
 // closing process.
 type Channel interface { //nolint:interfacebloat
 	// ChannelPoint returns the channel point of the target channel.
-	ChannelPoint() *wire.OutPoint
+	ChannelPoint() wire.OutPoint
 
 	// MarkCoopBroadcasted persistently marks that the channel close
 	// transaction has been broadcast.
diff --git a/lnwallet/channel.go b/lnwallet/channel.go
index 5e6af76c8..a34384876 100644
--- a/lnwallet/channel.go
+++ b/lnwallet/channel.go
@@ -1260,9 +1260,6 @@ type LightningChannel struct {
 
 	isClosed bool
 
-	// ChanPoint is the funding outpoint of this channel.
-	ChanPoint *wire.OutPoint
-
 	// sigPool is a pool of workers that are capable of signing and
 	// validating signatures in parallel. This is utilized as an
 	// optimization to void serially signing or validating the HTLC
@@ -1412,7 +1409,6 @@ func NewLightningChannel(signer input.Signer,
 		commitBuilder:        NewCommitmentBuilder(state),
 		localUpdateLog:       localUpdateLog,
 		remoteUpdateLog:      remoteUpdateLog,
-		ChanPoint:            &state.FundingOutpoint,
 		Capacity:             state.Capacity,
 		taprootNonceProducer: taprootNonceProducer,
 		log:                  build.NewPrefixLog(logPrefix, walletLog),
@@ -3564,7 +3560,7 @@ func (lc *LightningChannel) createCommitDiff(
 	// used on the wire to identify this channel. We'll use this shortly
 	// when recording the exact CommitSig message that we'll be sending
 	// out.
-	chanID := lnwire.NewChanIDFromOutPoint(&lc.channelState.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(lc.channelState.FundingOutpoint)
 
 	var (
 		logUpdates        []channeldb.LogUpdate
@@ -3684,7 +3680,7 @@ func (lc *LightningChannel) createCommitDiff(
 		Commitment: *diskCommit,
 		CommitSig: &lnwire.CommitSig{
 			ChanID: lnwire.NewChanIDFromOutPoint(
-				&lc.channelState.FundingOutpoint,
+				lc.channelState.FundingOutpoint,
 			),
 			CommitSig: commitSig,
 			HtlcSigs:  htlcSigs,
@@ -3702,7 +3698,7 @@ func (lc *LightningChannel) createCommitDiff(
 func (lc *LightningChannel) getUnsignedAckedUpdates() []channeldb.LogUpdate {
 	// First, we need to convert the funding outpoint into the ID that's
 	// used on the wire to identify this channel.
-	chanID := lnwire.NewChanIDFromOutPoint(&lc.channelState.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(lc.channelState.FundingOutpoint)
 
 	// Fetch the last remote update that we have signed for.
 	lastRemoteCommitted := lc.remoteCommitChain.tail().theirMessageIndex
@@ -4547,7 +4543,7 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
 			case err == nil:
 				commitSig := &lnwire.CommitSig{
 					ChanID: lnwire.NewChanIDFromOutPoint(
-						&lc.channelState.FundingOutpoint,
+						lc.channelState.FundingOutpoint,
 					),
 					CommitSig:  newCommit.CommitSig,
 					HtlcSigs:   newCommit.HtlcSigs,
@@ -5575,7 +5571,7 @@ func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.RevokeAndAck,
 		len(unsignedAckedUpdates))
 
 	revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint(
-		&lc.channelState.FundingOutpoint,
+		lc.channelState.FundingOutpoint,
 	)
 
 	return revocationMsg, newCommitment.Htlcs, finalHtlcs, nil
@@ -5642,7 +5638,7 @@ func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.RevokeAndAck) (
 	localChainTail := lc.localCommitChain.tail().height
 
 	source := lc.ShortChanID()
-	chanID := lnwire.NewChanIDFromOutPoint(&lc.channelState.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(lc.channelState.FundingOutpoint)
 
 	// Determine the set of htlcs that can be forwarded as a result of
 	// having received the revocation. We will simultaneously construct the
@@ -6430,8 +6426,8 @@ func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64, reason []byte,
 // ChannelPoint returns the outpoint of the original funding transaction which
 // created this active channel. This outpoint is used throughout various
 // subsystems to uniquely identify an open channel.
-func (lc *LightningChannel) ChannelPoint() *wire.OutPoint {
-	return &lc.channelState.FundingOutpoint
+func (lc *LightningChannel) ChannelPoint() wire.OutPoint {
+	return lc.channelState.FundingOutpoint
 }
 
 // ShortChanID returns the short channel ID for the channel. The short channel
@@ -8521,7 +8517,7 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd
 
 	revocationMsg.NextRevocationKey = input.ComputeCommitmentPoint(nextCommitSecret[:])
 	revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint(
-		&lc.channelState.FundingOutpoint,
+		lc.channelState.FundingOutpoint,
 	)
 
 	// If this is a taproot channel, then we also need to generate the
diff --git a/lnwire/channel_id.go b/lnwire/channel_id.go
index 0a9e08226..1615eb747 100644
--- a/lnwire/channel_id.go
+++ b/lnwire/channel_id.go
@@ -40,7 +40,7 @@ func (c ChannelID) String() string {
 // usable within the network. In order to convert the OutPoint into a ChannelID,
 // we XOR the lower 2-bytes of the txid within the OutPoint with the big-endian
 // serialization of the Index of the OutPoint, truncated to 2-bytes.
-func NewChanIDFromOutPoint(op *wire.OutPoint) ChannelID {
+func NewChanIDFromOutPoint(op wire.OutPoint) ChannelID {
 	// First we'll copy the txid of the outpoint into our channel ID slice.
 	var cid ChannelID
 	copy(cid[:], op.Hash[:])
@@ -85,7 +85,7 @@ func (c *ChannelID) GenPossibleOutPoints() [MaxFundingTxOutputs]wire.OutPoint {
 // IsChanPoint returns true if the OutPoint passed corresponds to the target
 // ChannelID.
 func (c ChannelID) IsChanPoint(op *wire.OutPoint) bool {
-	candidateCid := NewChanIDFromOutPoint(op)
+	candidateCid := NewChanIDFromOutPoint(*op)
 
 	return candidateCid == c
 }
diff --git a/netann/chan_status_manager.go b/netann/chan_status_manager.go
index 7ee543d2a..f536d7228 100644
--- a/netann/chan_status_manager.go
+++ b/netann/chan_status_manager.go
@@ -391,7 +391,7 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
 
 	// Quickly check to see if the requested channel is active within the
 	// htlcswitch and return an error if it isn't.
-	chanID := lnwire.NewChanIDFromOutPoint(&outpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(outpoint)
 	if !m.cfg.IsChannelActive(chanID) {
 		return ErrEnableInactiveChan
 	}
@@ -531,7 +531,7 @@ func (m *ChanStatusManager) markPendingInactiveChannels() {
 		// If our bookkeeping shows the channel as active, sample the
 		// htlcswitch to see if it believes the link is also active. If
 		// so, we will skip marking it as ChanStatusPendingDisabled.
-		chanID := lnwire.NewChanIDFromOutPoint(&c.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
 		if m.cfg.IsChannelActive(chanID) {
 			continue
 		}
diff --git a/peer/brontide.go b/peer/brontide.go
index 189fb1660..07fb5731e 100644
--- a/peer/brontide.go
+++ b/peer/brontide.go
@@ -834,7 +834,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
 				}
 
 				chanID := lnwire.NewChanIDFromOutPoint(
-					&dbChan.FundingOutpoint,
+					dbChan.FundingOutpoint,
 				)
 
 				// Fetch the second commitment point to send in
@@ -870,7 +870,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
 			return nil, err
 		}
 
-		chanPoint := &dbChan.FundingOutpoint
+		chanPoint := dbChan.FundingOutpoint
 
 		chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
@@ -932,7 +932,9 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
 		// need to fetch its current link-layer forwarding policy from
 		// the database.
 		graph := p.cfg.ChannelGraph
-		info, p1, p2, err := graph.FetchChannelEdgesByOutpoint(chanPoint)
+		info, p1, p2, err := graph.FetchChannelEdgesByOutpoint(
+			&chanPoint,
+		)
 		if err != nil && err != channeldb.ErrEdgeNotFound {
 			return nil, err
 		}
@@ -1020,7 +1022,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
 			}
 
 			chanID := lnwire.NewChanIDFromOutPoint(
-				&lnChan.State().FundingOutpoint,
+				lnChan.State().FundingOutpoint,
 			)
 
 			p.activeChanCloses[chanID] = chanCloser
@@ -1042,14 +1044,14 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
 
 		// Subscribe to the set of on-chain events for this channel.
 		chainEvents, err := p.cfg.ChainArb.SubscribeChannelEvents(
-			*chanPoint,
+			chanPoint,
 		)
 		if err != nil {
 			return nil, err
 		}
 
 		err = p.addLink(
-			chanPoint, lnChan, forwardingPolicy, chainEvents,
+			&chanPoint, lnChan, forwardingPolicy, chainEvents,
 			true, shutdownMsg,
 		)
 		if err != nil {
@@ -1144,7 +1146,7 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint,
 	// links going by the same channel id. If one is found, we'll shut it
 	// down to ensure that the mailboxes are only ever under the control of
 	// one link.
-	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(*chanPoint)
 	p.cfg.Switch.RemoveLink(chanID)
 
 	// With the channel link created, we'll now notify the htlc switch so
@@ -2815,16 +2817,16 @@ func chooseDeliveryScript(upfront,
 		return requested, nil
 	}
 
-	// If an upfront shutdown script was provided, and the user did not request
-	// a custom shutdown script, return the upfront address.
+	// If an upfront shutdown script was provided, and the user did not
+	// request a custom shutdown script, return the upfront address.
 	if len(requested) == 0 {
 		return upfront, nil
 	}
 
 	// If both an upfront shutdown script and a custom close script were
 	// provided, error if the user provided shutdown script does not match
-	// the upfront shutdown script (because closing out to a different script
-	// would violate upfront shutdown).
+	// the upfront shutdown script (because closing out to a different
+	// script would violate upfront shutdown).
 	if !bytes.Equal(upfront, requested) {
 		return nil, chancloser.ErrUpfrontShutdownScriptMismatch
 	}
@@ -2912,7 +2914,7 @@ func (p *Brontide) restartCoopClose(lnChan *lnwallet.LightningChannel) (
 	// This does not need a mutex even though it is in a different
 	// goroutine since this is done before the channelManager goroutine is
 	// created.
-	chanID := lnwire.NewChanIDFromOutPoint(&c.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
 	p.activeChanCloses[chanID] = chanCloser
 
 	// Create the Shutdown message.
@@ -2976,7 +2978,7 @@ func (p *Brontide) createChanCloser(channel *lnwallet.LightningChannel,
 // handleLocalCloseReq kicks-off the workflow to execute a cooperative or
 // forced unilateral closure of the channel initiated by a local subsystem.
 func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
-	chanID := lnwire.NewChanIDFromOutPoint(req.ChanPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(*req.ChanPoint)
 
 	channel, ok := p.activeChannels.Load(chanID)
 
@@ -3099,7 +3101,7 @@ type linkFailureReport struct {
 func (p *Brontide) handleLinkFailure(failure linkFailureReport) {
 	// Retrieve the channel from the map of active channels. We do this to
 	// have access to it even after WipeChannel remove it from the map.
-	chanID := lnwire.NewChanIDFromOutPoint(&failure.chanPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(failure.chanPoint)
 	lnChan, _ := p.activeChannels.Load(chanID)
 
 	// We begin by wiping the link, which will remove it from the switch,
@@ -3209,7 +3211,7 @@ func (p *Brontide) finalizeChanClosure(chanCloser *chancloser.ChanCloser) {
 
 	// First, we'll clear all indexes related to the channel in question.
 	chanPoint := chanCloser.Channel().ChannelPoint()
-	p.WipeChannel(chanPoint)
+	p.WipeChannel(&chanPoint)
 
 	// Also clear the activeChanCloses map of this channel.
 	cid := lnwire.NewChanIDFromOutPoint(chanPoint)
@@ -3247,7 +3249,7 @@ func (p *Brontide) finalizeChanClosure(chanCloser *chancloser.ChanCloser) {
 	}
 
 	go WaitForChanToClose(chanCloser.NegotiationHeight(), notifier, errChan,
-		chanPoint, &closingTxid, closingTx.TxOut[0].PkScript, func() {
+		&chanPoint, &closingTxid, closingTx.TxOut[0].PkScript, func() {
 			// Respond to the local subsystem which requested the
 			// channel closure.
 			if closeReq != nil {
@@ -3302,7 +3304,7 @@ func WaitForChanToClose(bestHeight uint32, notifier chainntnfs.ChainNotifier,
 // WipeChannel removes the passed channel point from all indexes associated with
 // the peer and the switch.
 func (p *Brontide) WipeChannel(chanPoint *wire.OutPoint) {
-	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(*chanPoint)
 
 	p.activeChannels.Delete(chanID)
 
@@ -3881,7 +3883,7 @@ func (p *Brontide) attachChannelEventSubscription() error {
 // updateNextRevocation updates the existing channel's next revocation if it's
 // nil.
 func (p *Brontide) updateNextRevocation(c *channeldb.OpenChannel) error {
-	chanPoint := &c.FundingOutpoint
+	chanPoint := c.FundingOutpoint
 	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	// Read the current channel.
@@ -3925,7 +3927,7 @@ func (p *Brontide) updateNextRevocation(c *channeldb.OpenChannel) error {
 // takes a `channeldb.OpenChannel`, creates a `lnwallet.LightningChannel` from
 // it and assembles it with a channel link.
 func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
-	chanPoint := &c.FundingOutpoint
+	chanPoint := c.FundingOutpoint
 	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	// If we've reached this point, there are two possible scenarios.  If
@@ -3960,7 +3962,7 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
 
 	// Next, we'll assemble a ChannelLink along with the necessary items it
 	// needs to function.
-	chainEvents, err := p.cfg.ChainArb.SubscribeChannelEvents(*chanPoint)
+	chainEvents, err := p.cfg.ChainArb.SubscribeChannelEvents(chanPoint)
 	if err != nil {
 		return fmt.Errorf("unable to subscribe to chain events: %w",
 			err)
@@ -3976,7 +3978,7 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
 
 	// Create the link and add it to the switch.
 	err = p.addLink(
-		chanPoint, lnChan, initialPolicy, chainEvents,
+		&chanPoint, lnChan, initialPolicy, chainEvents,
 		shouldReestablish, fn.None[lnwire.Shutdown](),
 	)
 	if err != nil {
@@ -3992,7 +3994,7 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
 // or init the next revocation for it.
 func (p *Brontide) handleNewActiveChannel(req *newChannelMsg) {
 	newChan := req.channel
-	chanPoint := &newChan.FundingOutpoint
+	chanPoint := newChan.FundingOutpoint
 	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	// Only update RemoteNextRevocation if the channel is in the
diff --git a/rpcserver.go b/rpcserver.go
index d55c97257..8c3d6b05c 100644
--- a/rpcserver.go
+++ b/rpcserver.go
@@ -2580,7 +2580,9 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
 			//  * so only need to grab from database
 			peer.WipeChannel(&channel.FundingOutpoint)
 		} else {
-			chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+			chanID := lnwire.NewChanIDFromOutPoint(
+				channel.FundingOutpoint,
+			)
 			r.server.htlcSwitch.RemoveLink(chanID)
 		}
 
@@ -2634,7 +2636,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
 
 		// If the link is not known by the switch, we cannot gracefully close
 		// the channel.
-		channelID := lnwire.NewChanIDFromOutPoint(chanPoint)
+		channelID := lnwire.NewChanIDFromOutPoint(*chanPoint)
 		if _, err := r.server.htlcSwitch.GetLink(channelID); err != nil {
 			rpcsLog.Debugf("Trying to non-force close offline channel with "+
 				"chan_point=%v", chanPoint)
@@ -2953,7 +2955,7 @@ func (r *rpcServer) GetInfo(_ context.Context,
 
 	var activeChannels uint32
 	for _, channel := range openChannels {
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 		if r.server.htlcSwitch.HasActiveLink(chanID) {
 			activeChannels++
 		}
@@ -4221,7 +4223,7 @@ func (r *rpcServer) ListChannels(ctx context.Context,
 			peerOnline = true
 		}
 
-		channelID := lnwire.NewChanIDFromOutPoint(&chanPoint)
+		channelID := lnwire.NewChanIDFromOutPoint(chanPoint)
 		var linkActive bool
 		if link, err := r.server.htlcSwitch.GetLink(channelID); err == nil {
 			// A channel is only considered active if it is known
@@ -4313,7 +4315,7 @@ func createRPCOpenChannel(r *rpcServer, dbChannel *channeldb.OpenChannel,
 	nodePub := dbChannel.IdentityPub
 	nodeID := hex.EncodeToString(nodePub.SerializeCompressed())
 	chanPoint := dbChannel.FundingOutpoint
-	chanID := lnwire.NewChanIDFromOutPoint(&chanPoint)
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	// As this is required for display purposes, we'll calculate
 	// the weight of the commitment transaction. We also add on the
diff --git a/server.go b/server.go
index 32dbc9cf0..a089a2238 100644
--- a/server.go
+++ b/server.go
@@ -1164,7 +1164,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
 		FeeEstimator: cc.FeeEstimator,
 		ChainIO:      cc.ChainIO,
 		MarkLinkInactive: func(chanPoint wire.OutPoint) error {
-			chanID := lnwire.NewChanIDFromOutPoint(&chanPoint)
+			chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 			s.htlcSwitch.RemoveLink(chanID)
 			return nil
 		},
@@ -1421,7 +1421,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
 			return s.chainArb.WatchNewChannel(channel)
 		},
 		ReportShortChanID: func(chanPoint wire.OutPoint) error {
-			cid := lnwire.NewChanIDFromOutPoint(&chanPoint)
+			cid := lnwire.NewChanIDFromOutPoint(chanPoint)
 			return s.htlcSwitch.UpdateShortChanID(cid)
 		},
 		RequiredRemoteChanReserve: func(chanAmt,
@@ -4633,7 +4633,7 @@ func (s *server) applyChannelUpdate(update *lnwire.ChannelUpdate,
 		defaultAlias lnwire.ShortChannelID
 	)
 
-	chanID := lnwire.NewChanIDFromOutPoint(op)
+	chanID := lnwire.NewChanIDFromOutPoint(*op)
 
 	// Fetch the peer's alias from the lnwire.ChannelID so it can be used
 	// in the ChannelUpdate if it hasn't been announced yet.
diff --git a/watchtower/wtclient/manager.go b/watchtower/wtclient/manager.go
index f1cae979f..01a9fa01e 100644
--- a/watchtower/wtclient/manager.go
+++ b/watchtower/wtclient/manager.go
@@ -780,7 +780,7 @@ func (m *Manager) handleChannelCloses(chanSub subscribe.Subscription) {
 			}
 
 			chanID := lnwire.NewChanIDFromOutPoint(
-				&event.CloseSummary.ChanPoint,
+				event.CloseSummary.ChanPoint,
 			)
 
 			log.Debugf("Received ClosedChannelEvent for "+


Test patch:
diff --git a/channeldb/db_test.go b/channeldb/db_test.go
index 62e720407..a954f2828 100644
--- a/channeldb/db_test.go
+++ b/channeldb/db_test.go
@@ -140,7 +140,7 @@ func TestFetchClosedChannelForID(t *testing.T) {
 		state.FundingOutpoint.Index = i
 
 		// We calculate the ChannelID and use it to fetch the summary.
-		cid := lnwire.NewChanIDFromOutPoint(&state.FundingOutpoint)
+		cid := lnwire.NewChanIDFromOutPoint(state.FundingOutpoint)
 		fetchedSummary, err := cdb.FetchClosedChannelForID(cid)
 		if err != nil {
 			t.Fatalf("unable to fetch close summary: %v", err)
@@ -158,7 +158,7 @@ func TestFetchClosedChannelForID(t *testing.T) {
 	// As a final test we make sure that we get ErrClosedChannelNotFound
 	// for a ChannelID we didn't add to the DB.
 	state.FundingOutpoint.Index++
-	cid := lnwire.NewChanIDFromOutPoint(&state.FundingOutpoint)
+	cid := lnwire.NewChanIDFromOutPoint(state.FundingOutpoint)
 	_, err = cdb.FetchClosedChannelForID(cid)
 	if err != ErrClosedChannelNotFound {
 		t.Fatalf("expected ErrClosedChannelNotFound, instead got: %v", err)
@@ -240,7 +240,7 @@ func TestFetchChannel(t *testing.T) {
 	require.Equal(t, channelState, dbChannel)
 
 	// Next, attempt to fetch the channel by its channel ID.
-	chanID := lnwire.NewChanIDFromOutPoint(&channelState.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(channelState.FundingOutpoint)
 	dbChannel, err = cdb.FetchChannelByID(nil, chanID)
 	require.NoError(t, err, "unable to fetch channel")
 
@@ -259,7 +259,7 @@ func TestFetchChannel(t *testing.T) {
 	_, err = cdb.FetchChannel(nil, channelState2.FundingOutpoint)
 	require.ErrorIs(t, err, ErrChannelNotFound)
 
-	chanID2 := lnwire.NewChanIDFromOutPoint(&channelState2.FundingOutpoint)
+	chanID2 := lnwire.NewChanIDFromOutPoint(channelState2.FundingOutpoint)
 	_, err = cdb.FetchChannelByID(nil, chanID2)
 	require.ErrorIs(t, err, ErrChannelNotFound)
 }
diff --git a/channeldb/forwarding_package_test.go b/channeldb/forwarding_package_test.go
index 1aabe7614..d796c6d51 100644
--- a/channeldb/forwarding_package_test.go
+++ b/channeldb/forwarding_package_test.go
@@ -141,7 +141,7 @@ func checkPkgFilterEncodeDecode(t *testing.T, i uint16, f *channeldb.PkgFilter)
 }
 
 var (
-	chanID = lnwire.NewChanIDFromOutPoint(&wire.OutPoint{})
+	chanID = lnwire.NewChanIDFromOutPoint(wire.OutPoint{})
 
 	adds = []channeldb.LogUpdate{
 		{
diff --git a/contractcourt/breach_arbitrator_test.go b/contractcourt/breach_arbitrator_test.go
index 29f33881a..fdc1239b4 100644
--- a/contractcourt/breach_arbitrator_test.go
+++ b/contractcourt/breach_arbitrator_test.go
@@ -1010,13 +1010,13 @@ func initBreachedState(t *testing.T) (*BreachArbitrator,
 func TestBreachHandoffSuccess(t *testing.T) {
 	brar, alice, _, bobClose, contractBreaches := initBreachedState(t)
 
-	chanPoint := alice.ChanPoint
+	chanPoint := alice.ChannelPoint()
 
 	// Signal a spend of the funding transaction and wait for the close
 	// observer to exit.
 	processACK := make(chan error)
 	breach := &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1044,13 +1044,13 @@ func TestBreachHandoffSuccess(t *testing.T) {
 	// After exiting, the breach arbiter should have persisted the
 	// retribution information and the channel should be shown as pending
 	// force closed.
-	assertArbiterBreach(t, brar, chanPoint)
+	assertArbiterBreach(t, brar, &chanPoint)
 
 	// Send another breach event. Since the handoff for this channel was
 	// already ACKed, the breach arbiter should immediately ACK and ignore
 	// this event.
 	breach = &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1077,7 +1077,7 @@ func TestBreachHandoffSuccess(t *testing.T) {
 	}
 
 	// State should not have changed.
-	assertArbiterBreach(t, brar, chanPoint)
+	assertArbiterBreach(t, brar, &chanPoint)
 }
 
 // TestBreachHandoffFail tests that a channel's close observer properly
@@ -1096,10 +1096,10 @@ func TestBreachHandoffFail(t *testing.T) {
 
 	// Signal the notifier to dispatch spend notifications of the funding
 	// transaction using the transaction from bob's closing summary.
-	chanPoint := alice.ChanPoint
+	chanPoint := alice.ChannelPoint()
 	processACK := make(chan error)
 	breach := &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1127,7 +1127,7 @@ func TestBreachHandoffFail(t *testing.T) {
 	// Since the handoff failed, the breach arbiter should not show the
 	// channel as breached, and the channel should also not have been marked
 	// pending closed.
-	assertNoArbiterBreach(t, brar, chanPoint)
+	assertNoArbiterBreach(t, brar, &chanPoint)
 	assertNotPendingClosed(t, alice)
 
 	brar, err := createTestArbiter(
@@ -1138,7 +1138,7 @@ func TestBreachHandoffFail(t *testing.T) {
 	// Signal a spend of the funding transaction and wait for the close
 	// observer to exit. This time we are allowing the handoff to succeed.
 	breach = &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1166,7 +1166,7 @@ func TestBreachHandoffFail(t *testing.T) {
 	// Check that the breach was properly recorded in the breach arbiter,
 	// and that the close observer marked the channel as pending closed
 	// before exiting.
-	assertArbiterBreach(t, brar, chanPoint)
+	assertArbiterBreach(t, brar, &chanPoint)
 }
 
 // TestBreachCreateJusticeTx tests that we create three different variants of
@@ -1560,7 +1560,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 	var (
 		height       = bobClose.ChanSnapshot.CommitHeight
 		forceCloseTx = bobClose.CloseTx
-		chanPoint    = alice.ChanPoint
+		chanPoint    = alice.ChannelPoint()
 		publTx       = make(chan *wire.MsgTx)
 		publErr      error
 		publMtx      sync.Mutex
@@ -1590,7 +1590,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 
 	processACK := make(chan error)
 	breach := &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1630,7 +1630,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 	// After exiting, the breach arbiter should have persisted the
 	// retribution information and the channel should be shown as pending
 	// force closed.
-	assertArbiterBreach(t, brar, chanPoint)
+	assertArbiterBreach(t, brar, &chanPoint)
 
 	// Assert that the database sees the channel as pending close, otherwise
 	// the breach arbiter won't be able to fully close it.
@@ -1669,7 +1669,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 	htlcOutpoint := retribution.HtlcRetributions[0].OutPoint
 
 	spendTxs, err := getSpendTransactions(
-		brar.cfg.Signer, chanPoint, retribution,
+		brar.cfg.Signer, &chanPoint, retribution,
 	)
 	require.NoError(t, err)
 
@@ -1764,7 +1764,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
 	}
 
 	// Assert that the channel is fully resolved.
-	assertBrarCleanup(t, brar, alice.ChanPoint, alice.State().Db)
+	assertBrarCleanup(t, brar, &chanPoint, alice.State().Db)
 }
 
 // TestBreachDelayedJusticeConfirmation tests that the breach arbiter will
@@ -1777,7 +1777,7 @@ func TestBreachDelayedJusticeConfirmation(t *testing.T) {
 		height       = bobClose.ChanSnapshot.CommitHeight
 		blockHeight  = int32(10)
 		forceCloseTx = bobClose.CloseTx
-		chanPoint    = alice.ChanPoint
+		chanPoint    = alice.ChannelPoint()
 		publTx       = make(chan *wire.MsgTx)
 	)
 
@@ -1799,7 +1799,7 @@ func TestBreachDelayedJusticeConfirmation(t *testing.T) {
 
 	processACK := make(chan error, 1)
 	breach := &ContractBreachEvent{
-		ChanPoint: *chanPoint,
+		ChanPoint: chanPoint,
 		ProcessACK: func(brarErr error) {
 			processACK <- brarErr
 		},
@@ -1840,7 +1840,7 @@ func TestBreachDelayedJusticeConfirmation(t *testing.T) {
 	// After exiting, the breach arbiter should have persisted the
 	// retribution information and the channel should be shown as pending
 	// force closed.
-	assertArbiterBreach(t, brar, chanPoint)
+	assertArbiterBreach(t, brar, &chanPoint)
 
 	// Assert that the database sees the channel as pending close, otherwise
 	// the breach arbiter won't be able to fully close it.
@@ -1965,7 +1965,7 @@ func TestBreachDelayedJusticeConfirmation(t *testing.T) {
 	}
 
 	// Assert that the channel is fully resolved.
-	assertBrarCleanup(t, brar, alice.ChanPoint, alice.State().Db)
+	assertBrarCleanup(t, brar, &chanPoint, alice.State().Db)
 }
 
 // findInputIndex returns the index of the input that spends from the given
@@ -2081,12 +2081,12 @@ func assertPendingClosed(t *testing.T, c *lnwallet.LightningChannel) {
 	require.NoError(t, err, "unable to load pending closed channels")
 
 	for _, chanSummary := range closedChans {
-		if chanSummary.ChanPoint == *c.ChanPoint {
+		if chanSummary.ChanPoint == c.ChannelPoint() {
 			return
 		}
 	}
 
-	t.Fatalf("channel %v was not marked pending closed", c.ChanPoint)
+	t.Fatalf("channel %v was not marked pending closed", c.ChannelPoint())
 }
 
 // assertNotPendingClosed checks that the channel has not been marked pending
@@ -2098,9 +2098,9 @@ func assertNotPendingClosed(t *testing.T, c *lnwallet.LightningChannel) {
 	require.NoError(t, err, "unable to load pending closed channels")
 
 	for _, chanSummary := range closedChans {
-		if chanSummary.ChanPoint == *c.ChanPoint {
+		if chanSummary.ChanPoint == c.ChannelPoint() {
 			t.Fatalf("channel %v was marked pending closed",
-				c.ChanPoint)
+				c.ChannelPoint())
 		}
 	}
 }
diff --git a/fn/slice_test.go b/fn/slice_test.go
deleted file mode 100644
index 0178cc946..000000000
--- a/fn/slice_test.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package fn
-
-import (
-	"slices"
-	"testing"
-
-	"github.com/stretchr/testify/require"
-)
-
-func even(a int) bool { return a%2 == 0 }
-func odd(a int) bool  { return a%2 != 0 }
-
-func TestAll(t *testing.T) {
-	x := []int{0, 2, 4, 6, 8}
-	require.True(t, All(even, x))
-	require.False(t, All(odd, x))
-
-	y := []int{1, 3, 5, 7, 9}
-	require.False(t, All(even, y))
-	require.True(t, All(odd, y))
-
-	z := []int{0, 2, 4, 6, 9}
-	require.False(t, All(even, z))
-	require.False(t, All(odd, z))
-}
-
-func TestAny(t *testing.T) {
-	x := []int{1, 3, 5, 7, 9}
-	require.False(t, Any(even, x))
-	require.True(t, Any(odd, x))
-
-	y := []int{0, 3, 5, 7, 9}
-	require.True(t, Any(even, y))
-	require.True(t, Any(odd, y))
-
-	z := []int{0, 2, 4, 6, 8}
-	require.True(t, Any(even, z))
-	require.False(t, Any(odd, z))
-}
-
-func TestMap(t *testing.T) {
-	inc := func(i int) int { return i + 1 }
-
-	x := []int{0, 2, 4, 6, 8}
-
-	y := Map(inc, x)
-
-	z := []int{1, 3, 5, 7, 9}
-
-	require.True(t, slices.Equal(y, z))
-}
-
-func TestFilter(t *testing.T) {
-	x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-
-	y := Filter(even, x)
-
-	require.True(t, All(even, y))
-
-	z := Filter(odd, y)
-
-	require.Zero(t, len(z))
-}
-
-func TestFoldl(t *testing.T) {
-	seed := []int{}
-	stupid := func(s []int, a int) []int { return append(s, a) }
-
-	x := []int{0, 1, 2, 3, 4}
-
-	r := Foldl(stupid, seed, x)
-
-	require.True(t, slices.Equal(x, r))
-}
-
-func TestFoldr(t *testing.T) {
-	seed := []int{}
-	stupid := func(a int, s []int) []int { return append(s, a) }
-
-	x := []int{0, 1, 2, 3, 4}
-
-	z := Foldr(stupid, seed, x)
-
-	slices.Reverse[[]int](x)
-
-	require.True(t, slices.Equal(x, z))
-}
-
-func TestFind(t *testing.T) {
-	x := []int{10, 11, 12, 13, 14, 15}
-
-	div3 := func(a int) bool { return a%3 == 0 }
-	div8 := func(a int) bool { return a%8 == 0 }
-
-	require.Equal(t, Find(div3, x), Some(12))
-
-	require.Equal(t, Find(div8, x), None[int]())
-}
-
-func TestFlatten(t *testing.T) {
-	x := [][]int{{0}, {1}, {2}}
-
-	y := Flatten(x)
-
-	require.True(t, slices.Equal(y, []int{0, 1, 2}))
-}
-
-func TestReplicate(t *testing.T) {
-	require.True(t, slices.Equal([]int{1, 1, 1, 1, 1}, Replicate(5, 1)))
-}
-
-func TestSpan(t *testing.T) {
-	x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	lt5 := func(a int) bool { return a < 5 }
-
-	low, high := Span(lt5, x)
-
-	require.True(t, slices.Equal(low, []int{0, 1, 2, 3, 4}))
-	require.True(t, slices.Equal(high, []int{5, 6, 7, 8, 9}))
-}
-
-func TestSplitAt(t *testing.T) {
-	x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	fst, snd := SplitAt(5, x)
-
-	require.True(t, slices.Equal(fst, []int{0, 1, 2, 3, 4}))
-	require.True(t, slices.Equal(snd, []int{5, 6, 7, 8, 9}))
-}
-
-func TestZipWith(t *testing.T) {
-	eq := func(a, b int) bool { return a == b }
-	x := []int{0, 1, 2, 3, 4}
-	y := Replicate(5, 1)
-	z := ZipWith(eq, x, y)
-	require.True(t, slices.Equal(
-		z, []bool{false, true, false, false, false},
-	))
-}
diff --git a/funding/manager_test.go b/funding/manager_test.go
index 6e1f22216..db61c3000 100644
--- a/funding/manager_test.go
+++ b/funding/manager_test.go
@@ -3365,7 +3365,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
 		t, alice, bob, func(node *testNode, msg *newChannelMsg) bool {
 			aliceDB := alice.fundingMgr.cfg.ChannelDB
 			chanID := lnwire.NewChanIDFromOutPoint(
-				&msg.channel.FundingOutpoint,
+				msg.channel.FundingOutpoint,
 			)
 
 			if node == alice {
diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go
index fdd2a0d6a..44836cf65 100644
--- a/htlcswitch/link_test.go
+++ b/htlcswitch/link_test.go
@@ -1497,7 +1497,7 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) {
 	// back the payment to Alice since he is unaware of Carol when the
 	// payment comes across.
 	bobChanID := lnwire.NewChanIDFromOutPoint(
-		&channels.bobToCarol.State().FundingOutpoint,
+		channels.bobToCarol.ChannelPoint(),
 	)
 	n.bobServer.htlcSwitch.RemoveLink(bobChanID)
 
@@ -3762,7 +3762,8 @@ func TestChannelRetransmission(t *testing.T) {
 			t.Fatalf("unable to create channel: %v", err)
 		}
 
-		chanID := lnwire.NewChanIDFromOutPoint(channels.aliceToBob.ChannelPoint())
+		chanPoint := channels.aliceToBob.ChannelPoint()
+		chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 		serverErr := make(chan error, 4)
 
 		aliceInterceptor := createInterceptorFunc("[alice] <-- [bob]",
diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go
index c566118d6..0c98fa4fe 100644
--- a/htlcswitch/test_utils.go
+++ b/htlcswitch/test_utils.go
@@ -73,7 +73,7 @@ func genID() (lnwire.ChannelID, lnwire.ShortChannelID) {
 	hash1, _ := chainhash.NewHash(bytes.Repeat(scratch[:], 4))
 
 	chanPoint1 := wire.NewOutPoint(hash1, uint32(id))
-	chanID1 := lnwire.NewChanIDFromOutPoint(chanPoint1)
+	chanID1 := lnwire.NewChanIDFromOutPoint(*chanPoint1)
 	aliceChanID := lnwire.NewShortChanIDFromInt(id)
 
 	return chanID1, aliceChanID
diff --git a/lnrpc/invoicesrpc/addinvoice_test.go b/lnrpc/invoicesrpc/addinvoice_test.go
index 1b15921d0..a384fd959 100644
--- a/lnrpc/invoicesrpc/addinvoice_test.go
+++ b/lnrpc/invoicesrpc/addinvoice_test.go
@@ -120,7 +120,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 		h.Mock.On(
 			"IsChannelActive", chanID,
 		).Once().Return(true)
@@ -137,7 +137,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 		h.Mock.On(
 			"IsChannelActive", chanID,
 		).Once().Return(false)
@@ -154,7 +154,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -178,7 +178,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -213,7 +213,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -251,7 +251,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 0,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -289,7 +289,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 1,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -340,7 +340,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 1,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -385,7 +385,7 @@ var shouldIncludeChannelTestCases = []struct {
 		fundingOutpoint := wire.OutPoint{
 			Index: 1,
 		}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 
 		h.Mock.On(
 			"IsChannelActive", chanID,
@@ -538,7 +538,7 @@ var populateHopHintsTestCases = []struct {
 		"hop hints allowed",
 	setupMock: func(h *hopHintsConfigMock) {
 		fundingOutpoint := wire.OutPoint{Index: 9}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 		allChannels := []*channeldb.OpenChannel{
 			{
 				FundingOutpoint: fundingOutpoint,
@@ -584,7 +584,7 @@ var populateHopHintsTestCases = []struct {
 	name: "populate hop hints stops when we reached the targeted bandwidth",
 	setupMock: func(h *hopHintsConfigMock) {
 		fundingOutpoint := wire.OutPoint{Index: 9}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 		remoteBalance := lnwire.MilliSatoshi(10_000_000)
 		allChannels := []*channeldb.OpenChannel{
 			{
@@ -635,7 +635,7 @@ var populateHopHintsTestCases = []struct {
 		"remote balance frist",
 	setupMock: func(h *hopHintsConfigMock) {
 		fundingOutpoint := wire.OutPoint{Index: 9}
-		chanID := lnwire.NewChanIDFromOutPoint(&fundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(fundingOutpoint)
 		remoteBalance := lnwire.MilliSatoshi(10_000_000)
 		allChannels := []*channeldb.OpenChannel{
 			// Because the channels with higher remote balance have
@@ -829,11 +829,11 @@ func setupMockTwoChannels(h *hopHintsConfigMock) (lnwire.ChannelID,
 	lnwire.ChannelID) {
 
 	fundingOutpoint1 := wire.OutPoint{Index: 9}
-	chanID1 := lnwire.NewChanIDFromOutPoint(&fundingOutpoint1)
+	chanID1 := lnwire.NewChanIDFromOutPoint(fundingOutpoint1)
 	remoteBalance1 := lnwire.MilliSatoshi(10_000_000)
 
 	fundingOutpoint2 := wire.OutPoint{Index: 2}
-	chanID2 := lnwire.NewChanIDFromOutPoint(&fundingOutpoint2)
+	chanID2 := lnwire.NewChanIDFromOutPoint(fundingOutpoint2)
 	remoteBalance2 := lnwire.MilliSatoshi(1_000_000)
 
 	allChannels := []*channeldb.OpenChannel{
diff --git a/lnwallet/chancloser/chancloser_test.go b/lnwallet/chancloser/chancloser_test.go
index 8111ef657..1956f0d2b 100644
--- a/lnwallet/chancloser/chancloser_test.go
+++ b/lnwallet/chancloser/chancloser_test.go
@@ -146,8 +146,8 @@ type mockChannel struct {
 	remoteKey keychain.KeyDescriptor
 }
 
-func (m *mockChannel) ChannelPoint() *wire.OutPoint {
-	return &m.chanPoint
+func (m *mockChannel) ChannelPoint() wire.OutPoint {
+	return m.chanPoint
 }
 
 func (m *mockChannel) MarkCoopBroadcasted(*wire.MsgTx, bool) error {
diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go
index 6717b9209..aa747bc42 100644
--- a/lnwallet/channel_test.go
+++ b/lnwallet/channel_test.go
@@ -3052,7 +3052,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
 	}
 
 	chanID := lnwire.NewChanIDFromOutPoint(
-		&aliceChannel.channelState.FundingOutpoint,
+		aliceChannel.channelState.FundingOutpoint,
 	)
 
 	// With the HTLC's applied to both update logs, we'll initiate a state
@@ -3419,7 +3419,7 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
 	require.NoError(t, err, "unable to create test channels")
 
 	chanID := lnwire.NewChanIDFromOutPoint(
-		&aliceChannel.channelState.FundingOutpoint,
+		aliceChannel.channelState.FundingOutpoint,
 	)
 
 	// We'll start the test with Bob extending a single HTLC to Alice, and
@@ -4682,7 +4682,7 @@ func TestChanSyncUnableToSync(t *testing.T) {
 	// state.
 	badChanSync := &lnwire.ChannelReestablish{
 		ChanID: lnwire.NewChanIDFromOutPoint(
-			&aliceChannel.channelState.FundingOutpoint,
+			aliceChannel.channelState.FundingOutpoint,
 		),
 		NextLocalCommitHeight:  1000,
 		RemoteCommitTailHeight: 9000,
diff --git a/lnwallet/transactions_test.go b/lnwallet/transactions_test.go
index 550586a4c..ab0ef7328 100644
--- a/lnwallet/transactions_test.go
+++ b/lnwallet/transactions_test.go
@@ -269,7 +269,7 @@ func addTestHtlcs(t *testing.T, remote, local *LightningChannel,
 		hash160map[hash160] = preimage
 
 		// Add htlc to the channel.
-		chanID := lnwire.NewChanIDFromOutPoint(remote.ChanPoint)
+		chanID := lnwire.NewChanIDFromOutPoint(remote.ChannelPoint())
 
 		msg := &lnwire.UpdateAddHTLC{
 			Amount:      htlc.amount,
diff --git a/lnwire/channel_id_test.go b/lnwire/channel_id_test.go
index 49f7b904b..a2aee4083 100644
--- a/lnwire/channel_id_test.go
+++ b/lnwire/channel_id_test.go
@@ -17,7 +17,7 @@ func TestChannelIDOutPointConversion(t *testing.T) {
 
 		// With the output index mutated, we'll convert it into a
 		// ChannelID.
-		cid := NewChanIDFromOutPoint(&testChanPoint)
+		cid := NewChanIDFromOutPoint(testChanPoint)
 
 		// Once the channel point has been converted to a channelID, it
 		// should recognize its original outpoint.
@@ -48,7 +48,7 @@ func TestGenPossibleOutPoints(t *testing.T) {
 	// We'll first convert out test outpoint into a ChannelID.
 	testChanPoint := *outpoint1
 	testChanPoint.Index = 24
-	chanID := NewChanIDFromOutPoint(&testChanPoint)
+	chanID := NewChanIDFromOutPoint(testChanPoint)
 
 	// With the chan ID created, we'll generate all possible root outpoints
 	// given this channel ID.
diff --git a/netann/chan_status_manager_test.go b/netann/chan_status_manager_test.go
index cb871ba01..1e64a53f8 100644
--- a/netann/chan_status_manager_test.go
+++ b/netann/chan_status_manager_test.go
@@ -391,7 +391,7 @@ func (h *testHarness) markActive(channels []*channeldb.OpenChannel) {
 	h.t.Helper()
 
 	for _, channel := range channels {
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 		h.htlcSwitch.SetStatus(chanID, true)
 	}
 }
@@ -402,7 +402,7 @@ func (h *testHarness) markInactive(channels []*channeldb.OpenChannel) {
 	h.t.Helper()
 
 	for _, channel := range channels {
-		chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
+		chanID := lnwire.NewChanIDFromOutPoint(channel.FundingOutpoint)
 		h.htlcSwitch.SetStatus(chanID, false)
 	}
 }
diff --git a/peer/brontide_test.go b/peer/brontide_test.go
index c88aeed96..46c1bec4d 100644
--- a/peer/brontide_test.go
+++ b/peer/brontide_test.go
@@ -53,7 +53,8 @@ func TestPeerChannelClosureShutdownResponseLinkRemoved(t *testing.T) {
 	)
 	require.NoError(t, err, "unable to create test channels")
 
-	chanID := lnwire.NewChanIDFromOutPoint(bobChan.ChannelPoint())
+	chanPoint := bobChan.ChannelPoint()
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	dummyDeliveryScript := genScript(t, p2wshAddress)
 
@@ -100,7 +101,8 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) {
 	)
 	require.NoError(t, err, "unable to create test channels")
 
-	chanID := lnwire.NewChanIDFromOutPoint(bobChan.ChannelPoint())
+	chanPoint := bobChan.ChannelPoint()
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	mockLink := newMockUpdateHandler(chanID)
 	mockSwitch.links = append(mockSwitch.links, mockLink)
@@ -204,7 +206,8 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
 	)
 	require.NoError(t, err, "unable to create test channels")
 
-	chanID := lnwire.NewChanIDFromOutPoint(bobChan.ChannelPoint())
+	chanPoint := bobChan.ChannelPoint()
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 	mockLink := newMockUpdateHandler(chanID)
 	mockSwitch.links = append(mockSwitch.links, mockLink)
 
@@ -215,7 +218,7 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
 	errChan := make(chan error, 1)
 	closeCommand := &htlcswitch.ChanClose{
 		CloseType:      contractcourt.CloseRegular,
-		ChanPoint:      bobChan.ChannelPoint(),
+		ChanPoint:      &chanPoint,
 		Updates:        updateChan,
 		TargetFeePerKw: 12500,
 		Err:            errChan,
@@ -327,7 +330,8 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) {
 	)
 	require.NoError(t, err, "unable to create test channels")
 
-	chanID := lnwire.NewChanIDFromOutPoint(bobChan.ChannelPoint())
+	chanPoint := bobChan.ChannelPoint()
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 
 	mockLink := newMockUpdateHandler(chanID)
 	mockSwitch.links = append(mockSwitch.links, mockLink)
@@ -513,7 +517,8 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
 	)
 	require.NoError(t, err, "unable to create test channels")
 
-	chanID := lnwire.NewChanIDFromOutPoint(bobChan.ChannelPoint())
+	chanPoint := bobChan.ChannelPoint()
+	chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
 	mockLink := newMockUpdateHandler(chanID)
 	mockSwitch.links = append(mockSwitch.links, mockLink)
 
@@ -522,7 +527,7 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
 	errChan := make(chan error, 1)
 	closeCommand := &htlcswitch.ChanClose{
 		CloseType:      contractcourt.CloseRegular,
-		ChanPoint:      bobChan.ChannelPoint(),
+		ChanPoint:      &chanPoint,
 		Updates:        updateChan,
 		TargetFeePerKw: 12500,
 		Err:            errChan,
@@ -854,7 +859,7 @@ func TestCustomShutdownScript(t *testing.T) {
 			errChan := make(chan error, 1)
 			closeCommand := htlcswitch.ChanClose{
 				CloseType:      contractcourt.CloseRegular,
-				ChanPoint:      chanPoint,
+				ChanPoint:      &chanPoint,
 				Updates:        updateChan,
 				TargetFeePerKw: 12500,
 				DeliveryScript: test.userCloseScript,
@@ -1213,7 +1218,7 @@ func TestUpdateNextRevocation(t *testing.T) {
 	// Test an error is returned when the chanID's corresponding channel is
 	// nil.
 	testChannel.FundingOutpoint = wire.OutPoint{Index: 1}
-	chanID := lnwire.NewChanIDFromOutPoint(&testChannel.FundingOutpoint)
+	chanID := lnwire.NewChanIDFromOutPoint(testChannel.FundingOutpoint)
 	alicePeer.activeChannels.Store(chanID, nil)
 
 	err = alicePeer.updateNextRevocation(testChannel)