rpc: detect dangling satoshi amounts, display as CommitFee in ListChannels

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.
This commit is contained in:
Olaoluwa Osuntokun 2017-12-10 17:09:53 -08:00
parent 8a351a7388
commit 60791d83d5
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
1 changed files with 20 additions and 3 deletions

View File

@ -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()),