From 60791d83d5100dc7e5c7b1dfc0eb7e83c4a3052b Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sun, 10 Dec 2017 17:09:53 -0800 Subject: [PATCH] rpc: detect dangling satoshi amounts, display as CommitFee in ListChannels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit we fix a cosmetic bug within our RPC output for list channels. We have a policy of always showing SAT instead of mSAT externally. This led to user confusion, as if Alice or Bob ended up with a fractional amount of satoshis, then the sum of trimmed amount would be silently sent to miner’s fees. An example being: Alice ending up with `8998999 mSAT` (`8998.999 SAT`). Bob similarly ends up with `1001001 mSAT` (`1001.001 SAT`). `8998.999 + 1001.001 = 10000.0 SAT`. However, we can't express that fractional amount (totaling `1 SAT` across both commitment transactions) so it goes to miner fees. To remedy this on the RPC interface level, we’ll now detect if we have a dangling satoshi, and properly list it as going towards the miner fee on the commitment transaction. Fixes #468. --- rpcserver.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index c92550bc..681014bc 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1482,15 +1482,32 @@ func (r *rpcServer) ListChannels(ctx context.Context, commitBaseWeight := blockchain.GetTransactionWeight(utx) commitWeight := commitBaseWeight + lnwallet.WitnessCommitmentTxWeight + localBalance := localCommit.LocalBalance + remoteBalance := localCommit.RemoteBalance + commitFee := localCommit.CommitFee + + // As an artefact of our usage of mSAT internally, either party + // may end up in a state where they're holding a fractional + // amount of satoshis which can't be expressed within the + // actual commitment output. Since we round down when going + // from mSAT -> SAT, we may at any point be adding an + // additional SAT to miners fees. We'll detect this, and + // display the proper commitment fee in this case. + externalCommitFee := (dbChannel.Capacity - localBalance.ToSatoshis() - + remoteBalance.ToSatoshis()) + if commitFee != externalCommitFee { + commitFee = externalCommitFee + } + channel := &lnrpc.ActiveChannel{ Active: peerOnline && linkActive, RemotePubkey: nodeID, ChannelPoint: chanPoint.String(), ChanId: chanID, Capacity: int64(dbChannel.Capacity), - LocalBalance: int64(localCommit.LocalBalance.ToSatoshis()), - RemoteBalance: int64(localCommit.RemoteBalance.ToSatoshis()), - CommitFee: int64(localCommit.CommitFee), + LocalBalance: int64(localBalance.ToSatoshis()), + RemoteBalance: int64(remoteBalance.ToSatoshis()), + CommitFee: int64(commitFee), CommitWeight: commitWeight, FeePerKw: int64(localCommit.FeePerKw), TotalSatoshisSent: int64(dbChannel.TotalMSatSent.ToSatoshis()),