lnd+rpc: update RPC responses to convert mSAT to SAT

This commit is contained in:
Olaoluwa Osuntokun 2017-08-21 23:25:41 -07:00
parent ad00266451
commit 01b0ddf1c5
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
9 changed files with 146 additions and 84 deletions

@ -212,7 +212,7 @@ type fundingConfig struct {
// channel extended to it. The function is able to take into account // channel extended to it. The function is able to take into account
// the amount of the channel, and any funds we'll be pushed in the // the amount of the channel, and any funds we'll be pushed in the
// process to determine how many confirmations we'll require. // process to determine how many confirmations we'll require.
NumRequiredConfs func(btcutil.Amount, btcutil.Amount) uint16 NumRequiredConfs func(btcutil.Amount, lnwire.MilliSatoshi) uint16
// RequiredRemoteDelay is a function that maps the total amount in a // RequiredRemoteDelay is a function that maps the total amount in a
// proposed channel to the CSV delay that we'll require for the remote // proposed channel to the CSV delay that we'll require for the remote
@ -596,8 +596,8 @@ func (f *fundingManager) handlePendingChannels(msg *pendingChansReq) {
identityPub: dbPendingChan.IdentityPub, identityPub: dbPendingChan.IdentityPub,
channelPoint: &dbPendingChan.FundingOutpoint, channelPoint: &dbPendingChan.FundingOutpoint,
capacity: dbPendingChan.Capacity, capacity: dbPendingChan.Capacity,
localBalance: dbPendingChan.LocalBalance, localBalance: dbPendingChan.LocalBalance.ToSatoshis(),
remoteBalance: dbPendingChan.RemoteBalance, remoteBalance: dbPendingChan.RemoteBalance.ToSatoshis(),
} }
pendingChannels = append(pendingChannels, pendingChan) pendingChannels = append(pendingChannels, pendingChan)
@ -762,7 +762,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
DustLimit: msg.DustLimit, DustLimit: msg.DustLimit,
MaxPendingAmount: msg.MaxValueInFlight, MaxPendingAmount: msg.MaxValueInFlight,
ChanReserve: msg.ChannelReserve, ChanReserve: msg.ChannelReserve,
MinHTLC: btcutil.Amount(msg.HtlcMinimum), MinHTLC: msg.HtlcMinimum,
MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs, MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
}, },
CsvDelay: remoteCsvDelay, CsvDelay: remoteCsvDelay,
@ -791,7 +791,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
MaxValueInFlight: ourContribution.MaxPendingAmount, MaxValueInFlight: ourContribution.MaxPendingAmount,
ChannelReserve: ourContribution.ChanReserve, ChannelReserve: ourContribution.ChanReserve,
MinAcceptDepth: uint32(numConfsReq), MinAcceptDepth: uint32(numConfsReq),
HtlcMinimum: uint32(ourContribution.MinHTLC), HtlcMinimum: ourContribution.MinHTLC,
CsvDelay: uint16(remoteCsvDelay), CsvDelay: uint16(remoteCsvDelay),
FundingKey: ourContribution.MultiSigKey, FundingKey: ourContribution.MultiSigKey,
RevocationPoint: ourContribution.RevocationBasePoint, RevocationPoint: ourContribution.RevocationBasePoint,
@ -859,7 +859,7 @@ func (f *fundingManager) handleFundingAccept(fmsg *fundingAcceptMsg) {
DustLimit: msg.DustLimit, DustLimit: msg.DustLimit,
MaxPendingAmount: msg.MaxValueInFlight, MaxPendingAmount: msg.MaxValueInFlight,
ChanReserve: msg.ChannelReserve, ChanReserve: msg.ChannelReserve,
MinHTLC: btcutil.Amount(msg.HtlcMinimum), MinHTLC: msg.HtlcMinimum,
MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs, MaxAcceptedHtlcs: msg.MaxAcceptedHTLCs,
}, },
MultiSigKey: copyPubKey(msg.FundingKey), MultiSigKey: copyPubKey(msg.FundingKey),
@ -1406,13 +1406,15 @@ func (f *fundingManager) sendFundingLockedAndAnnounceChannel(
return return
} }
// TODO(roasbeef): wait 6 blocks before announcing
f.sendChannelAnnouncement(completeChan, channel, shortChanID) f.sendChannelAnnouncement(completeChan, channel, shortChanID)
} }
// sendChannelAnnouncement broadcast the neccessary channel announcement // sendChannelAnnouncement broadcast the necessary channel announcement
// messages to the network. Should be called after the fundingLocked message is // messages to the network. Should be called after the fundingLocked message
// sent (channelState is 'fundingLockedSent') and the channel is ready to be // is sent (channelState is 'fundingLockedSent') and the channel is ready to
// used. // be used.
func (f *fundingManager) sendChannelAnnouncement(completeChan *channeldb.OpenChannel, func (f *fundingManager) sendChannelAnnouncement(completeChan *channeldb.OpenChannel,
channel *lnwallet.LightningChannel, shortChanID *lnwire.ShortChannelID) { channel *lnwallet.LightningChannel, shortChanID *lnwire.ShortChannelID) {
@ -1432,8 +1434,9 @@ func (f *fundingManager) sendChannelAnnouncement(completeChan *channeldb.OpenCha
return return
} }
// After the channel is successully announced from the fundingManager, // After the channel is successfully announced from the
// we delete the channel from our internal database. We can do this // fundingManager, we delete the channel from our internal database.
// We can do this
// because we assume the AuthenticatedGossiper queues the announcement // because we assume the AuthenticatedGossiper queues the announcement
// messages, and persists them in case of a daemon shutdown. // messages, and persists them in case of a daemon shutdown.
err = f.deleteChannelOpeningState(&completeChan.FundingOutpoint) err = f.deleteChannelOpeningState(&completeChan.FundingOutpoint)
@ -1495,6 +1498,8 @@ func (f *fundingManager) handleFundingLocked(fmsg *fundingLockedMsg) {
return return
} }
// TODO(roasbeef): done nothing if repeat message sent
// The funding locked message contains the next commitment point we'll // The funding locked message contains the next commitment point we'll
// need to create the next commitment state for the remote party. So // need to create the next commitment state for the remote party. So
// we'll insert that into the channel now before passing it along to // we'll insert that into the channel now before passing it along to
@ -1615,10 +1620,11 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu
chanUpdateAnn := &lnwire.ChannelUpdate{ chanUpdateAnn := &lnwire.ChannelUpdate{
ShortChannelID: shortChanID, ShortChannelID: shortChanID,
ChainHash: chainHash,
Timestamp: uint32(time.Now().Unix()), Timestamp: uint32(time.Now().Unix()),
Flags: chanFlags, Flags: chanFlags,
TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta), TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta),
HtlcMinimumMsat: uint64(f.cfg.DefaultRoutingPolicy.MinHTLC), HtlcMinimumMsat: f.cfg.DefaultRoutingPolicy.MinHTLC,
BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee), BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee),
FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate), FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate),
} }
@ -1642,8 +1648,8 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu
// need two signatures: one under the identity public key used which // need two signatures: one under the identity public key used which
// signs the message itself and another signature of the identity // signs the message itself and another signature of the identity
// public key under the funding key itself. // public key under the funding key itself.
// TODO(roasbeef): need to revisit, ensure signatures are signed //
// properly // TODO(roasbeef): use SignAnnouncement here instead?
chanAnnMsg, err := chanAnn.DataToSign() chanAnnMsg, err := chanAnn.DataToSign()
if err != nil { if err != nil {
return nil, err return nil, err

@ -208,7 +208,9 @@ func createTestFundingManager(t *testing.T, pubKey *btcec.PublicKey,
t.Fatal("did not expect FindChannel to be called") t.Fatal("did not expect FindChannel to be called")
return nil, nil return nil, nil
}, },
NumRequiredConfs: func(chanAmt btcutil.Amount, pushAmt btcutil.Amount) uint16 { NumRequiredConfs: func(chanAmt btcutil.Amount,
pushAmt lnwire.MilliSatoshi) uint16 {
return uint16(cfg.DefaultNumChanConfs) return uint16(cfg.DefaultNumChanConfs)
}, },
RequiredRemoteDelay: func(amt btcutil.Amount) uint16 { RequiredRemoteDelay: func(amt btcutil.Amount) uint16 {
@ -382,7 +384,7 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
targetPubkey: bob.privKey.PubKey(), targetPubkey: bob.privKey.PubKey(),
chainHash: *activeNetParams.GenesisHash, chainHash: *activeNetParams.GenesisHash,
localFundingAmt: localFundingAmt, localFundingAmt: localFundingAmt,
pushAmt: pushAmt, pushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
updates: updateChan, updates: updateChan,
err: errChan, err: errChan,
} }
@ -404,8 +406,8 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
errorMsg, gotError := aliceMsg.(*lnwire.Error) errorMsg, gotError := aliceMsg.(*lnwire.Error)
if gotError { if gotError {
t.Fatalf("expected OpenChannel to be sent "+ t.Fatalf("expected OpenChannel to be sent "+
"from bob, instead got error: (%v) %v", "from bob, instead got error: %v",
errorMsg.Code, string(errorMsg.Data)) lnwire.ErrorCode(errorMsg.Data[0]))
} }
t.Fatalf("expected OpenChannel to be sent from "+ t.Fatalf("expected OpenChannel to be sent from "+
"alice, instead got %T", aliceMsg) "alice, instead got %T", aliceMsg)
@ -427,8 +429,8 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
errorMsg, gotError := bobMsg.(*lnwire.Error) errorMsg, gotError := bobMsg.(*lnwire.Error)
if gotError { if gotError {
t.Fatalf("expected AcceptChannel to be sent "+ t.Fatalf("expected AcceptChannel to be sent "+
"from bob, instead got error: (%v) %v", "from bob, instead got error: %v",
errorMsg.Code, string(errorMsg.Data)) lnwire.ErrorCode(errorMsg.Data[0]))
} }
t.Fatalf("expected AcceptChannel to be sent from bob, "+ t.Fatalf("expected AcceptChannel to be sent from bob, "+
"instead got %T", bobMsg) "instead got %T", bobMsg)
@ -448,8 +450,8 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
errorMsg, gotError := aliceMsg.(*lnwire.Error) errorMsg, gotError := aliceMsg.(*lnwire.Error)
if gotError { if gotError {
t.Fatalf("expected FundingCreated to be sent "+ t.Fatalf("expected FundingCreated to be sent "+
"from bob, instead got error: (%v) %v", "from bob, instead got error: %v",
errorMsg.Code, string(errorMsg.Data)) lnwire.ErrorCode(errorMsg.Data[0]))
} }
t.Fatalf("expected FundingCreated to be sent from "+ t.Fatalf("expected FundingCreated to be sent from "+
"alice, instead got %T", aliceMsg) "alice, instead got %T", aliceMsg)
@ -470,8 +472,8 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
errorMsg, gotError := bobMsg.(*lnwire.Error) errorMsg, gotError := bobMsg.(*lnwire.Error)
if gotError { if gotError {
t.Fatalf("expected FundingSigned to be "+ t.Fatalf("expected FundingSigned to be "+
"sent from bob, instead got error: (%v) %v", "sent from bob, instead got error: %v",
errorMsg.Code, string(errorMsg.Data)) lnwire.ErrorCode(errorMsg.Data[0]))
} }
t.Fatalf("expected FundingSigned to be sent from "+ t.Fatalf("expected FundingSigned to be sent from "+
"bob, instead got %T", bobMsg) "bob, instead got %T", bobMsg)

@ -8,6 +8,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcutil" "github.com/roasbeef/btcutil"
) )
@ -63,7 +64,7 @@ func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash
invoice := &channeldb.Invoice{ invoice := &channeldb.Invoice{
CreationDate: time.Now(), CreationDate: time.Now(),
Terms: channeldb.ContractTerm{ Terms: channeldb.ContractTerm{
Value: amt, Value: lnwire.NewMSatFromSatoshis(amt),
PaymentPreimage: preimage, PaymentPreimage: preimage,
}, },
} }

2
lnd.go

@ -210,7 +210,7 @@ func lndMain() error {
return nil, fmt.Errorf("unable to find channel") return nil, fmt.Errorf("unable to find channel")
}, },
DefaultRoutingPolicy: activeChainControl.routingPolicy, DefaultRoutingPolicy: activeChainControl.routingPolicy,
NumRequiredConfs: func(chanAmt btcutil.Amount, pushAmt btcutil.Amount) uint16 { NumRequiredConfs: func(chanAmt btcutil.Amount, pushAmt lnwire.MilliSatoshi) uint16 {
// TODO(roasbeef): add configurable mapping // TODO(roasbeef): add configurable mapping
// * simple switch initially // * simple switch initially
// * assign coefficient, etc // * assign coefficient, etc

@ -1430,7 +1430,7 @@ func (p *peer) handleClosingSigned(localReq *htlcswitch.ChanClose,
ClosingTXID: closingTxid, ClosingTXID: closingTxid,
RemotePub: &chanInfo.RemoteIdentity, RemotePub: &chanInfo.RemoteIdentity,
Capacity: chanInfo.Capacity, Capacity: chanInfo.Capacity,
SettledBalance: chanInfo.LocalBalance, SettledBalance: chanInfo.LocalBalance.ToSatoshis(),
CloseType: channeldb.CooperativeClose, CloseType: channeldb.CooperativeClose,
IsPending: true, IsPending: true,
} }
@ -1769,7 +1769,7 @@ func createGetLastUpdate(router *routing.ChannelRouter,
Timestamp: uint32(time.Now().Unix()), Timestamp: uint32(time.Now().Unix()),
Flags: local.Flags, Flags: local.Flags,
TimeLockDelta: local.TimeLockDelta, TimeLockDelta: local.TimeLockDelta,
HtlcMinimumMsat: uint64(local.MinHTLC), HtlcMinimumMsat: local.MinHTLC,
BaseFee: uint32(local.FeeBaseMSat), BaseFee: uint32(local.FeeBaseMSat),
FeeRate: uint32(local.FeeProportionalMillionths), FeeRate: uint32(local.FeeProportionalMillionths),
}, nil }, nil

@ -246,6 +246,7 @@ func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error)
chanID := lnwire.NewShortChanIDFromInt( chanID := lnwire.NewShortChanIDFromInt(
chanClose.ChanID, chanClose.ChanID,
) )
pilot.OnChannelClose(chanID) pilot.OnChannelClose(chanID)
} }

@ -70,12 +70,12 @@ type rpcServer struct {
started int32 // To be used atomically. started int32 // To be used atomically.
shutdown int32 // To be used atomically. shutdown int32 // To be used atomically.
server *server
// authSvc is the authentication/authorization service backed by // authSvc is the authentication/authorization service backed by
// macaroons. // macaroons.
authSvc *bakery.Service authSvc *bakery.Service
server *server
wg sync.WaitGroup wg sync.WaitGroup
quit chan struct{} quit chan struct{}
@ -94,8 +94,7 @@ func newRPCServer(s *server, authSvc *bakery.Service) *rpcServer {
} }
} }
// Start launches any helper goroutines required for the rpcServer // Start launches any helper goroutines required for the rpcServer to function.
// to function.
func (r *rpcServer) Start() error { func (r *rpcServer) Start() error {
if atomic.AddInt32(&r.started, 1) != 1 { if atomic.AddInt32(&r.started, 1) != 1 {
return nil return nil
@ -154,6 +153,7 @@ func (r *rpcServer) sendCoinsOnChain(paymentMap map[string]int64) (*chainhash.Ha
// SendMany, this RPC call only allows creating a single output at a time. // SendMany, this RPC call only allows creating a single output at a time.
func (r *rpcServer) SendCoins(ctx context.Context, func (r *rpcServer) SendCoins(ctx context.Context,
in *lnrpc.SendCoinsRequest) (*lnrpc.SendCoinsResponse, error) { in *lnrpc.SendCoinsRequest) (*lnrpc.SendCoinsResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "sendcoins", if err := macaroons.ValidateMacaroon(ctx, "sendcoins",
@ -179,6 +179,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
// outputs in parallel. // outputs in parallel.
func (r *rpcServer) SendMany(ctx context.Context, func (r *rpcServer) SendMany(ctx context.Context,
in *lnrpc.SendManyRequest) (*lnrpc.SendManyResponse, error) { in *lnrpc.SendManyRequest) (*lnrpc.SendManyResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "sendcoins", if err := macaroons.ValidateMacaroon(ctx, "sendcoins",
@ -200,6 +201,7 @@ func (r *rpcServer) SendMany(ctx context.Context,
// NewAddress creates a new address under control of the local wallet. // NewAddress creates a new address under control of the local wallet.
func (r *rpcServer) NewAddress(ctx context.Context, func (r *rpcServer) NewAddress(ctx context.Context,
in *lnrpc.NewAddressRequest) (*lnrpc.NewAddressResponse, error) { in *lnrpc.NewAddressRequest) (*lnrpc.NewAddressResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "newaddress", if err := macaroons.ValidateMacaroon(ctx, "newaddress",
@ -233,6 +235,7 @@ func (r *rpcServer) NewAddress(ctx context.Context,
// the local wallet. // the local wallet.
func (r *rpcServer) NewWitnessAddress(ctx context.Context, func (r *rpcServer) NewWitnessAddress(ctx context.Context,
in *lnrpc.NewWitnessAddressRequest) (*lnrpc.NewAddressResponse, error) { in *lnrpc.NewWitnessAddressRequest) (*lnrpc.NewAddressResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "newaddress", if err := macaroons.ValidateMacaroon(ctx, "newaddress",
@ -256,6 +259,7 @@ func (r *rpcServer) NewWitnessAddress(ctx context.Context,
// verification. // verification.
func (r *rpcServer) SignMessage(ctx context.Context, func (r *rpcServer) SignMessage(ctx context.Context,
in *lnrpc.SignMessageRequest) (*lnrpc.SignMessageResponse, error) { in *lnrpc.SignMessageRequest) (*lnrpc.SignMessageResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "signmessage", if err := macaroons.ValidateMacaroon(ctx, "signmessage",
@ -283,6 +287,7 @@ func (r *rpcServer) SignMessage(ctx context.Context,
// VerifyMessage also returns the recovered pubkey from the signature. // VerifyMessage also returns the recovered pubkey from the signature.
func (r *rpcServer) VerifyMessage(ctx context.Context, func (r *rpcServer) VerifyMessage(ctx context.Context,
in *lnrpc.VerifyMessageRequest) (*lnrpc.VerifyMessageResponse, error) { in *lnrpc.VerifyMessageRequest) (*lnrpc.VerifyMessageResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "verifymessage", if err := macaroons.ValidateMacaroon(ctx, "verifymessage",
@ -329,6 +334,7 @@ func (r *rpcServer) VerifyMessage(ctx context.Context,
// ConnectPeer attempts to establish a connection to a remote peer. // ConnectPeer attempts to establish a connection to a remote peer.
func (r *rpcServer) ConnectPeer(ctx context.Context, func (r *rpcServer) ConnectPeer(ctx context.Context,
in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) { in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "connectpeer", if err := macaroons.ValidateMacaroon(ctx, "connectpeer",
@ -397,6 +403,7 @@ func (r *rpcServer) ConnectPeer(ctx context.Context,
// with the target peer, this action will be disallowed. // with the target peer, this action will be disallowed.
func (r *rpcServer) DisconnectPeer(ctx context.Context, func (r *rpcServer) DisconnectPeer(ctx context.Context,
in *lnrpc.DisconnectPeerRequest) (*lnrpc.DisconnectPeerResponse, error) { in *lnrpc.DisconnectPeerRequest) (*lnrpc.DisconnectPeerResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "disconnectpeer", if err := macaroons.ValidateMacaroon(ctx, "disconnectpeer",
@ -453,6 +460,7 @@ func (r *rpcServer) DisconnectPeer(ctx context.Context,
// request to a remote peer. // request to a remote peer.
func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
updateStream lnrpc.Lightning_OpenChannelServer) error { updateStream lnrpc.Lightning_OpenChannelServer) error {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(updateStream.Context(), if err := macaroons.ValidateMacaroon(updateStream.Context(),
@ -476,6 +484,8 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// Ensure that the initial balance of the remote party (if pushing // Ensure that the initial balance of the remote party (if pushing
// satoshis) does not exceed the amount the local party has requested // satoshis) does not exceed the amount the local party has requested
// for funding. // for funding.
//
// TODO(roasbeef): incorporate base fee?
if remoteInitialBalance >= localFundingAmt { if remoteInitialBalance >= localFundingAmt {
return fmt.Errorf("amount pushed to remote peer for initial " + return fmt.Errorf("amount pushed to remote peer for initial " +
"state must be below the local funding amount") "state must be below the local funding amount")
@ -531,8 +541,10 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// Instruct the server to trigger the necessary events to attempt to // Instruct the server to trigger the necessary events to attempt to
// open a new channel. A stream is returned in place, this stream will // open a new channel. A stream is returned in place, this stream will
// be used to consume updates of the state of the pending channel. // be used to consume updates of the state of the pending channel.
updateChan, errChan := r.server.OpenChannel(in.TargetPeerId, updateChan, errChan := r.server.OpenChannel(
nodePubKey, localFundingAmt, remoteInitialBalance) in.TargetPeerId, nodePubKey, localFundingAmt,
lnwire.NewMSatFromSatoshis(remoteInitialBalance),
)
var outpoint wire.OutPoint var outpoint wire.OutPoint
out: out:
@ -580,6 +592,7 @@ out:
// strings. // strings.
func (r *rpcServer) OpenChannelSync(ctx context.Context, func (r *rpcServer) OpenChannelSync(ctx context.Context,
in *lnrpc.OpenChannelRequest) (*lnrpc.ChannelPoint, error) { in *lnrpc.OpenChannelRequest) (*lnrpc.ChannelPoint, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "openchannel", if err := macaroons.ValidateMacaroon(ctx, "openchannel",
@ -634,8 +647,10 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
"initial state must be below the local funding amount") "initial state must be below the local funding amount")
} }
updateChan, errChan := r.server.OpenChannel(in.TargetPeerId, updateChan, errChan := r.server.OpenChannel(
nodepubKey, localFundingAmt, remoteInitialBalance) in.TargetPeerId, nodepubKey, localFundingAmt,
lnwire.NewMSatFromSatoshis(remoteInitialBalance),
)
select { select {
// If an error occurs them immediately return the error to the client. // If an error occurs them immediately return the error to the client.
@ -670,6 +685,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
// a force close after a timeout period in the case of an inactive peer. // a force close after a timeout period in the case of an inactive peer.
func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest, func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
updateStream lnrpc.Lightning_CloseChannelServer) error { updateStream lnrpc.Lightning_CloseChannelServer) error {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(updateStream.Context(), if err := macaroons.ValidateMacaroon(updateStream.Context(),
@ -903,8 +919,9 @@ func (r *rpcServer) forceCloseChan(channel *lnwallet.LightningChannel) (*chainha
// close channel summary. // close channel summary.
if closeSummary.SelfOutputSignDesc != nil || if closeSummary.SelfOutputSignDesc != nil ||
len(closeSummary.HtlcResolutions) == 0 { len(closeSummary.HtlcResolutions) == 0 {
closeInfo.SettledBalance = chanInfo.LocalBalance
closeInfo.TimeLockedBalance = chanInfo.LocalBalance closeInfo.SettledBalance = chanInfo.LocalBalance.ToSatoshis()
closeInfo.TimeLockedBalance = chanInfo.LocalBalance.ToSatoshis()
} }
if err := channel.DeleteState(closeInfo); err != nil { if err := channel.DeleteState(closeInfo); err != nil {
@ -923,6 +940,7 @@ func (r *rpcServer) forceCloseChan(channel *lnwallet.LightningChannel) (*chainha
// concerning the number of open+pending channels. // concerning the number of open+pending channels.
func (r *rpcServer) GetInfo(ctx context.Context, func (r *rpcServer) GetInfo(ctx context.Context,
in *lnrpc.GetInfoRequest) (*lnrpc.GetInfoResponse, error) { in *lnrpc.GetInfoRequest) (*lnrpc.GetInfoResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "getinfo", if err := macaroons.ValidateMacaroon(ctx, "getinfo",
@ -979,6 +997,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
// ListPeers returns a verbose listing of all currently active peers. // ListPeers returns a verbose listing of all currently active peers.
func (r *rpcServer) ListPeers(ctx context.Context, func (r *rpcServer) ListPeers(ctx context.Context,
in *lnrpc.ListPeersRequest) (*lnrpc.ListPeersResponse, error) { in *lnrpc.ListPeersRequest) (*lnrpc.ListPeersResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "listpeers", if err := macaroons.ValidateMacaroon(ctx, "listpeers",
@ -995,8 +1014,6 @@ func (r *rpcServer) ListPeers(ctx context.Context,
} }
for _, serverPeer := range serverPeers { for _, serverPeer := range serverPeers {
// TODO(roasbeef): add a snapshot method which grabs peer read mtx
var ( var (
satSent int64 satSent int64
satRecv int64 satRecv int64
@ -1009,8 +1026,8 @@ func (r *rpcServer) ListPeers(ctx context.Context,
// peer. // peer.
chans := serverPeer.ChannelSnapshots() chans := serverPeer.ChannelSnapshots()
for _, c := range chans { for _, c := range chans {
satSent += int64(c.TotalSatoshisSent) satSent += int64(c.TotalMilliSatoshisSent.ToSatoshis())
satRecv += int64(c.TotalSatoshisReceived) satRecv += int64(c.TotalMilliSatoshisReceived.ToSatoshis())
} }
nodePub := serverPeer.addr.IdentityKey.SerializeCompressed() nodePub := serverPeer.addr.IdentityKey.SerializeCompressed()
@ -1041,6 +1058,7 @@ func (r *rpcServer) ListPeers(ctx context.Context,
// TODO(roasbeef): add async hooks into wallet balance changes // TODO(roasbeef): add async hooks into wallet balance changes
func (r *rpcServer) WalletBalance(ctx context.Context, func (r *rpcServer) WalletBalance(ctx context.Context,
in *lnrpc.WalletBalanceRequest) (*lnrpc.WalletBalanceResponse, error) { in *lnrpc.WalletBalanceRequest) (*lnrpc.WalletBalanceResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "walletbalance", if err := macaroons.ValidateMacaroon(ctx, "walletbalance",
@ -1065,6 +1083,7 @@ func (r *rpcServer) WalletBalance(ctx context.Context,
// channels in satoshis. // channels in satoshis.
func (r *rpcServer) ChannelBalance(ctx context.Context, func (r *rpcServer) ChannelBalance(ctx context.Context,
in *lnrpc.ChannelBalanceRequest) (*lnrpc.ChannelBalanceResponse, error) { in *lnrpc.ChannelBalanceRequest) (*lnrpc.ChannelBalanceResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "channelbalance", if err := macaroons.ValidateMacaroon(ctx, "channelbalance",
@ -1081,7 +1100,7 @@ func (r *rpcServer) ChannelBalance(ctx context.Context,
var balance btcutil.Amount var balance btcutil.Amount
for _, channel := range channels { for _, channel := range channels {
if !channel.IsPending { if !channel.IsPending {
balance += channel.LocalBalance balance += channel.LocalBalance.ToSatoshis()
} }
} }
@ -1094,6 +1113,7 @@ func (r *rpcServer) ChannelBalance(ctx context.Context,
// process of closure, either initiated cooperatively or non-cooperatively. // process of closure, either initiated cooperatively or non-cooperatively.
func (r *rpcServer) PendingChannels(ctx context.Context, func (r *rpcServer) PendingChannels(ctx context.Context,
in *lnrpc.PendingChannelRequest) (*lnrpc.PendingChannelResponse, error) { in *lnrpc.PendingChannelRequest) (*lnrpc.PendingChannelResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "listchannels", if err := macaroons.ValidateMacaroon(ctx, "listchannels",
@ -1134,8 +1154,8 @@ func (r *rpcServer) PendingChannels(ctx context.Context,
RemoteNodePub: hex.EncodeToString(pub), RemoteNodePub: hex.EncodeToString(pub),
ChannelPoint: pendingChan.FundingOutpoint.String(), ChannelPoint: pendingChan.FundingOutpoint.String(),
Capacity: int64(pendingChan.Capacity), Capacity: int64(pendingChan.Capacity),
LocalBalance: int64(pendingChan.LocalBalance), LocalBalance: int64(pendingChan.LocalBalance.ToSatoshis()),
RemoteBalance: int64(pendingChan.RemoteBalance), RemoteBalance: int64(pendingChan.RemoteBalance.ToSatoshis()),
}, },
CommitWeight: commitWeight, CommitWeight: commitWeight,
CommitFee: int64(pendingChan.CommitFee), CommitFee: int64(pendingChan.CommitFee),
@ -1234,6 +1254,7 @@ func (r *rpcServer) PendingChannels(ctx context.Context,
// is a participant in. // is a participant in.
func (r *rpcServer) ListChannels(ctx context.Context, func (r *rpcServer) ListChannels(ctx context.Context,
in *lnrpc.ListChannelsRequest) (*lnrpc.ListChannelsResponse, error) { in *lnrpc.ListChannelsRequest) (*lnrpc.ListChannelsResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "listchannels", if err := macaroons.ValidateMacaroon(ctx, "listchannels",
@ -1288,13 +1309,13 @@ func (r *rpcServer) ListChannels(ctx context.Context,
ChannelPoint: chanPoint.String(), ChannelPoint: chanPoint.String(),
ChanId: chanID, ChanId: chanID,
Capacity: int64(dbChannel.Capacity), Capacity: int64(dbChannel.Capacity),
LocalBalance: int64(dbChannel.LocalBalance), LocalBalance: int64(dbChannel.LocalBalance.ToSatoshis()),
RemoteBalance: int64(dbChannel.RemoteBalance), RemoteBalance: int64(dbChannel.RemoteBalance.ToSatoshis()),
CommitFee: int64(dbChannel.CommitFee), CommitFee: int64(dbChannel.CommitFee),
CommitWeight: commitWeight, CommitWeight: commitWeight,
FeePerKw: int64(dbChannel.FeePerKw), FeePerKw: int64(dbChannel.FeePerKw),
TotalSatoshisSent: int64(dbChannel.TotalSatoshisSent), TotalSatoshisSent: int64(dbChannel.TotalMSatSent.ToSatoshis()),
TotalSatoshisReceived: int64(dbChannel.TotalSatoshisReceived), TotalSatoshisReceived: int64(dbChannel.TotalMSatReceived.ToSatoshis()),
NumUpdates: dbChannel.NumUpdates, NumUpdates: dbChannel.NumUpdates,
PendingHtlcs: make([]*lnrpc.HTLC, len(dbChannel.Htlcs)), PendingHtlcs: make([]*lnrpc.HTLC, len(dbChannel.Htlcs)),
} }
@ -1316,8 +1337,7 @@ func (r *rpcServer) ListChannels(ctx context.Context,
// savePayment saves a successfully completed payment to the database for // savePayment saves a successfully completed payment to the database for
// historical record keeping. // historical record keeping.
func (r *rpcServer) savePayment(route *routing.Route, amount btcutil.Amount, func (r *rpcServer) savePayment(route *routing.Route, amount lnwire.MilliSatoshi, rHash []byte) error {
rHash []byte) error {
paymentPath := make([][33]byte, len(route.Hops)) paymentPath := make([][33]byte, len(route.Hops))
for i, hop := range route.Hops { for i, hop := range route.Hops {
@ -1357,6 +1377,9 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
errChan := make(chan error, 1) errChan := make(chan error, 1)
payChan := make(chan *lnrpc.SendRequest) payChan := make(chan *lnrpc.SendRequest)
// TODO(roasbeef): enforce fee limits, pass into router, ditch if exceed limit
// * limit either a %, or absolute, or iff more than sending
// We don't allow payments to be sent while the daemon itself is still // We don't allow payments to be sent while the daemon itself is still
// syncing as we may be trying to sent a payment over a "stale" // syncing as we may be trying to sent a payment over a "stale"
// channel. // channel.
@ -1604,6 +1627,7 @@ func (r *rpcServer) SendPaymentSync(ctx context.Context,
// unique payment preimage. // unique payment preimage.
func (r *rpcServer) AddInvoice(ctx context.Context, func (r *rpcServer) AddInvoice(ctx context.Context,
invoice *lnrpc.Invoice) (*lnrpc.AddInvoiceResponse, error) { invoice *lnrpc.Invoice) (*lnrpc.AddInvoiceResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "addinvoice", if err := macaroons.ValidateMacaroon(ctx, "addinvoice",
@ -1645,8 +1669,11 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
"(maxsize=%v)", len(invoice.Receipt), channeldb.MaxReceiptSize) "(maxsize=%v)", len(invoice.Receipt), channeldb.MaxReceiptSize)
} }
// Finally, the value of an invoice MUST NOT be zero. amt := btcutil.Amount(invoice.Value)
if invoice.Value == 0 { amtMSat := lnwire.NewMSatFromSatoshis(amt)
switch {
// The value of an invoice MUST NOT be zero.
case invoice.Value == 0:
return nil, fmt.Errorf("zero value invoices are disallowed") return nil, fmt.Errorf("zero value invoices are disallowed")
} }
@ -1655,7 +1682,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
Memo: []byte(invoice.Memo), Memo: []byte(invoice.Memo),
Receipt: invoice.Receipt, Receipt: invoice.Receipt,
Terms: channeldb.ContractTerm{ Terms: channeldb.ContractTerm{
Value: btcutil.Amount(invoice.Value), Value: amtMSat,
}, },
} }
copy(i.Terms.PaymentPreimage[:], paymentPreimage[:]) copy(i.Terms.PaymentPreimage[:], paymentPreimage[:])
@ -1675,11 +1702,11 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
rHash := sha256.Sum256(paymentPreimage[:]) rHash := sha256.Sum256(paymentPreimage[:])
// Finally we also create an encoded payment request which allows the // Finally we also create an encoded payment request which allows the
// caller to comactly send the invoice to the payer. // caller to compactly send the invoice to the payer.
payReqString := zpay32.Encode(&zpay32.PaymentRequest{ payReqString := zpay32.Encode(&zpay32.PaymentRequest{
Destination: r.server.identityPriv.PubKey(), Destination: r.server.identityPriv.PubKey(),
PaymentHash: rHash, PaymentHash: rHash,
Amount: btcutil.Amount(invoice.Value), Amount: amt,
}) })
return &lnrpc.AddInvoiceResponse{ return &lnrpc.AddInvoiceResponse{
@ -1693,6 +1720,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
// returned. // returned.
func (r *rpcServer) LookupInvoice(ctx context.Context, func (r *rpcServer) LookupInvoice(ctx context.Context,
req *lnrpc.PaymentHash) (*lnrpc.Invoice, error) { req *lnrpc.PaymentHash) (*lnrpc.Invoice, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "readinvoices", if err := macaroons.ValidateMacaroon(ctx, "readinvoices",
@ -1738,18 +1766,19 @@ func (r *rpcServer) LookupInvoice(ctx context.Context,
})) }))
preimage := invoice.Terms.PaymentPreimage preimage := invoice.Terms.PaymentPreimage
satAmt := invoice.Terms.Value.ToSatoshis()
return &lnrpc.Invoice{ return &lnrpc.Invoice{
Memo: string(invoice.Memo[:]), Memo: string(invoice.Memo[:]),
Receipt: invoice.Receipt[:], Receipt: invoice.Receipt[:],
RHash: rHash, RHash: rHash,
RPreimage: preimage[:], RPreimage: preimage[:],
Value: int64(invoice.Terms.Value), Value: int64(satAmt),
CreationDate: invoice.CreationDate.Unix(), CreationDate: invoice.CreationDate.Unix(),
Settled: invoice.Terms.Settled, Settled: invoice.Terms.Settled,
PaymentRequest: zpay32.Encode(&zpay32.PaymentRequest{ PaymentRequest: zpay32.Encode(&zpay32.PaymentRequest{
Destination: r.server.identityPriv.PubKey(), Destination: r.server.identityPriv.PubKey(),
PaymentHash: sha256.Sum256(preimage[:]), PaymentHash: sha256.Sum256(preimage[:]),
Amount: invoice.Terms.Value, Amount: satAmt,
}), }),
}, nil }, nil
} }
@ -1758,6 +1787,7 @@ func (r *rpcServer) LookupInvoice(ctx context.Context,
// database. Any active debug invoices are ignored. // database. Any active debug invoices are ignored.
func (r *rpcServer) ListInvoices(ctx context.Context, func (r *rpcServer) ListInvoices(ctx context.Context,
req *lnrpc.ListInvoiceRequest) (*lnrpc.ListInvoiceResponse, error) { req *lnrpc.ListInvoiceRequest) (*lnrpc.ListInvoiceResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "readinvoices", if err := macaroons.ValidateMacaroon(ctx, "readinvoices",
@ -1773,7 +1803,7 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
invoices := make([]*lnrpc.Invoice, len(dbInvoices)) invoices := make([]*lnrpc.Invoice, len(dbInvoices))
for i, dbInvoice := range dbInvoices { for i, dbInvoice := range dbInvoices {
invoiceAmount := dbInvoice.Terms.Value invoiceAmount := dbInvoice.Terms.Value.ToSatoshis()
paymentPreimge := dbInvoice.Terms.PaymentPreimage[:] paymentPreimge := dbInvoice.Terms.PaymentPreimage[:]
rHash := sha256.Sum256(paymentPreimge) rHash := sha256.Sum256(paymentPreimge)
@ -1804,6 +1834,7 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
// notifying the client of newly added/settled invoices. // notifying the client of newly added/settled invoices.
func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription, func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription,
updateStream lnrpc.Lightning_SubscribeInvoicesServer) error { updateStream lnrpc.Lightning_SubscribeInvoicesServer) error {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(updateStream.Context(), if err := macaroons.ValidateMacaroon(updateStream.Context(),
@ -1826,7 +1857,7 @@ func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription,
Receipt: settledInvoice.Receipt[:], Receipt: settledInvoice.Receipt[:],
RHash: rHash[:], RHash: rHash[:],
RPreimage: preImage, RPreimage: preImage,
Value: int64(settledInvoice.Terms.Value), Value: int64(settledInvoice.Terms.Value.ToSatoshis()),
Settled: settledInvoice.Terms.Settled, Settled: settledInvoice.Terms.Settled,
} }
if err := updateStream.Send(invoice); err != nil { if err := updateStream.Send(invoice); err != nil {
@ -1843,6 +1874,7 @@ func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription,
// over. // over.
func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest, func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest,
updateStream lnrpc.Lightning_SubscribeTransactionsServer) error { updateStream lnrpc.Lightning_SubscribeTransactionsServer) error {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(updateStream.Context(), if err := macaroons.ValidateMacaroon(updateStream.Context(),
@ -1891,6 +1923,7 @@ func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest,
// relevant to the wallet. // relevant to the wallet.
func (r *rpcServer) GetTransactions(ctx context.Context, func (r *rpcServer) GetTransactions(ctx context.Context,
_ *lnrpc.GetTransactionsRequest) (*lnrpc.TransactionDetails, error) { _ *lnrpc.GetTransactionsRequest) (*lnrpc.TransactionDetails, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "gettransactions", if err := macaroons.ValidateMacaroon(ctx, "gettransactions",
@ -1931,6 +1964,7 @@ func (r *rpcServer) GetTransactions(ctx context.Context,
// information, etc. // information, etc.
func (r *rpcServer) DescribeGraph(ctx context.Context, func (r *rpcServer) DescribeGraph(ctx context.Context,
_ *lnrpc.ChannelGraphRequest) (*lnrpc.ChannelGraph, error) { _ *lnrpc.ChannelGraphRequest) (*lnrpc.ChannelGraph, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "describegraph", if err := macaroons.ValidateMacaroon(ctx, "describegraph",
@ -2037,8 +2071,11 @@ func marshalDbEdge(edgeInfo *channeldb.ChannelEdgeInfo,
// given channel identified by its channel ID: an 8-byte integer which uniquely // given channel identified by its channel ID: an 8-byte integer which uniquely
// identifies the location of transaction's funding output within the block // identifies the location of transaction's funding output within the block
// chain. // chain.
func (r *rpcServer) GetChanInfo(ctx context.Context, in *lnrpc.ChanInfoRequest) (*lnrpc.ChannelEdge, error) { func (r *rpcServer) GetChanInfo(ctx context.Context,
in *lnrpc.ChanInfoRequest) (*lnrpc.ChannelEdge, error) {
graph := r.server.chanDB.ChannelGraph() graph := r.server.chanDB.ChannelGraph()
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "getchaninfo", if err := macaroons.ValidateMacaroon(ctx, "getchaninfo",
@ -2062,7 +2099,9 @@ func (r *rpcServer) GetChanInfo(ctx context.Context, in *lnrpc.ChanInfoRequest)
// GetNodeInfo returns the latest advertised and aggregate authenticated // GetNodeInfo returns the latest advertised and aggregate authenticated
// channel information for the specified node identified by its public key. // channel information for the specified node identified by its public key.
func (r *rpcServer) GetNodeInfo(ctx context.Context, in *lnrpc.NodeInfoRequest) (*lnrpc.NodeInfo, error) { func (r *rpcServer) GetNodeInfo(ctx context.Context,
in *lnrpc.NodeInfoRequest) (*lnrpc.NodeInfo, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "getnodeinfo", if err := macaroons.ValidateMacaroon(ctx, "getnodeinfo",
@ -2099,7 +2138,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, in *lnrpc.NodeInfoRequest)
totalCapcity btcutil.Amount totalCapcity btcutil.Amount
) )
if err := node.ForEachChannel(nil, func(_ *bolt.Tx, edge *channeldb.ChannelEdgeInfo, if err := node.ForEachChannel(nil, func(_ *bolt.Tx, edge *channeldb.ChannelEdgeInfo,
_ *channeldb.ChannelEdgePolicy) error { _, _ *channeldb.ChannelEdgePolicy) error {
numChannels++ numChannels++
totalCapcity += edge.Capacity totalCapcity += edge.Capacity
@ -2140,6 +2179,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, in *lnrpc.NodeInfoRequest)
// * create separate PR to send based on well formatted route // * create separate PR to send based on well formatted route
func (r *rpcServer) QueryRoutes(ctx context.Context, func (r *rpcServer) QueryRoutes(ctx context.Context,
in *lnrpc.QueryRoutesRequest) (*lnrpc.QueryRoutesResponse, error) { in *lnrpc.QueryRoutesRequest) (*lnrpc.QueryRoutesResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "queryroutes", if err := macaroons.ValidateMacaroon(ctx, "queryroutes",
@ -2183,16 +2223,16 @@ func (r *rpcServer) QueryRoutes(ctx context.Context,
func marshalRoute(route *routing.Route) *lnrpc.Route { func marshalRoute(route *routing.Route) *lnrpc.Route {
resp := &lnrpc.Route{ resp := &lnrpc.Route{
TotalTimeLock: route.TotalTimeLock, TotalTimeLock: route.TotalTimeLock,
TotalFees: int64(route.TotalFees), TotalFees: int64(route.TotalFees.ToSatoshis()),
TotalAmt: int64(route.TotalAmount), TotalAmt: int64(route.TotalAmount.ToSatoshis()),
Hops: make([]*lnrpc.Hop, len(route.Hops)), Hops: make([]*lnrpc.Hop, len(route.Hops)),
} }
for i, hop := range route.Hops { for i, hop := range route.Hops {
resp.Hops[i] = &lnrpc.Hop{ resp.Hops[i] = &lnrpc.Hop{
ChanId: hop.Channel.ChannelID, ChanId: hop.Channel.ChannelID,
ChanCapacity: int64(hop.Channel.Capacity), ChanCapacity: int64(hop.Channel.Capacity),
AmtToForward: int64(hop.AmtToForward), AmtToForward: int64(hop.AmtToForward.ToSatoshis()),
Fee: int64(hop.Fee), Fee: int64(hop.Fee.ToSatoshis()),
Expiry: uint32(hop.OutgoingTimeLock), Expiry: uint32(hop.OutgoingTimeLock),
} }
} }
@ -2202,7 +2242,9 @@ func marshalRoute(route *routing.Route) *lnrpc.Route {
// GetNetworkInfo returns some basic stats about the known channel graph from // GetNetworkInfo returns some basic stats about the known channel graph from
// the PoV of the node. // the PoV of the node.
func (r *rpcServer) GetNetworkInfo(ctx context.Context, _ *lnrpc.NetworkInfoRequest) (*lnrpc.NetworkInfo, error) { func (r *rpcServer) GetNetworkInfo(ctx context.Context,
_ *lnrpc.NetworkInfoRequest) (*lnrpc.NetworkInfo, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "getnetworkinfo", if err := macaroons.ValidateMacaroon(ctx, "getnetworkinfo",
@ -2242,7 +2284,7 @@ func (r *rpcServer) GetNetworkInfo(ctx context.Context, _ *lnrpc.NetworkInfoRequ
// re-use it within this inner view. // re-use it within this inner view.
var outDegree uint32 var outDegree uint32
if err := node.ForEachChannel(tx, func(_ *bolt.Tx, if err := node.ForEachChannel(tx, func(_ *bolt.Tx,
edge *channeldb.ChannelEdgeInfo, _ *channeldb.ChannelEdgePolicy) error { edge *channeldb.ChannelEdgeInfo, _, _ *channeldb.ChannelEdgePolicy) error {
// Bump up the out degree for this node for each // Bump up the out degree for this node for each
// channel encountered. // channel encountered.
@ -2323,7 +2365,9 @@ func (r *rpcServer) GetNetworkInfo(ctx context.Context, _ *lnrpc.NetworkInfoRequ
// StopDaemon will send a shutdown request to the interrupt handler, triggering // StopDaemon will send a shutdown request to the interrupt handler, triggering
// a graceful shutdown of the daemon. // a graceful shutdown of the daemon.
func (r *rpcServer) StopDaemon(ctx context.Context, _ *lnrpc.StopRequest) (*lnrpc.StopResponse, error) { func (r *rpcServer) StopDaemon(ctx context.Context,
_ *lnrpc.StopRequest) (*lnrpc.StopResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "stopdaemon", if err := macaroons.ValidateMacaroon(ctx, "stopdaemon",
@ -2344,6 +2388,7 @@ func (r *rpcServer) StopDaemon(ctx context.Context, _ *lnrpc.StopRequest) (*lnrp
// and finally when prior channels are closed on-chain. // and finally when prior channels are closed on-chain.
func (r *rpcServer) SubscribeChannelGraph(req *lnrpc.GraphTopologySubscription, func (r *rpcServer) SubscribeChannelGraph(req *lnrpc.GraphTopologySubscription,
updateStream lnrpc.Lightning_SubscribeChannelGraphServer) error { updateStream lnrpc.Lightning_SubscribeChannelGraphServer) error {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(updateStream.Context(), if err := macaroons.ValidateMacaroon(updateStream.Context(),
@ -2464,6 +2509,7 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol
// ListPayments returns a list of all outgoing payments. // ListPayments returns a list of all outgoing payments.
func (r *rpcServer) ListPayments(ctx context.Context, func (r *rpcServer) ListPayments(ctx context.Context,
_ *lnrpc.ListPaymentsRequest) (*lnrpc.ListPaymentsResponse, error) { _ *lnrpc.ListPaymentsRequest) (*lnrpc.ListPaymentsResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "listpayments", if err := macaroons.ValidateMacaroon(ctx, "listpayments",
@ -2490,7 +2536,7 @@ func (r *rpcServer) ListPayments(ctx context.Context,
paymentsResp.Payments[i] = &lnrpc.Payment{ paymentsResp.Payments[i] = &lnrpc.Payment{
PaymentHash: hex.EncodeToString(payment.PaymentHash[:]), PaymentHash: hex.EncodeToString(payment.PaymentHash[:]),
Value: int64(payment.Terms.Value), Value: int64(payment.Terms.Value.ToSatoshis()),
CreationDate: payment.CreationDate.Unix(), CreationDate: payment.CreationDate.Unix(),
Path: path, Path: path,
} }
@ -2502,6 +2548,7 @@ func (r *rpcServer) ListPayments(ctx context.Context,
// DeleteAllPayments deletes all outgoing payments from DB. // DeleteAllPayments deletes all outgoing payments from DB.
func (r *rpcServer) DeleteAllPayments(ctx context.Context, func (r *rpcServer) DeleteAllPayments(ctx context.Context,
_ *lnrpc.DeleteAllPaymentsRequest) (*lnrpc.DeleteAllPaymentsResponse, error) { _ *lnrpc.DeleteAllPaymentsRequest) (*lnrpc.DeleteAllPaymentsResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "deleteallpayments", if err := macaroons.ValidateMacaroon(ctx, "deleteallpayments",
@ -2520,8 +2567,9 @@ func (r *rpcServer) DeleteAllPayments(ctx context.Context,
} }
// SetAlias... // SetAlias...
func (r *rpcServer) SetAlias(ctx context.Context, _ *lnrpc.SetAliasRequest) (*lnrpc.SetAliasResponse, error) { func (r *rpcServer) SetAlias(ctx context.Context,
// Check macaroon to see if this is allowed. _ *lnrpc.SetAliasRequest) (*lnrpc.SetAliasResponse, error) {
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "setalias", if err := macaroons.ValidateMacaroon(ctx, "setalias",
r.authSvc); err != nil { r.authSvc); err != nil {
@ -2538,6 +2586,7 @@ func (r *rpcServer) SetAlias(ctx context.Context, _ *lnrpc.SetAliasRequest) (*ln
// sub-system. // sub-system.
func (r *rpcServer) DebugLevel(ctx context.Context, func (r *rpcServer) DebugLevel(ctx context.Context,
req *lnrpc.DebugLevelRequest) (*lnrpc.DebugLevelResponse, error) { req *lnrpc.DebugLevelRequest) (*lnrpc.DebugLevelResponse, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "debuglevel", if err := macaroons.ValidateMacaroon(ctx, "debuglevel",
@ -2570,6 +2619,7 @@ func (r *rpcServer) DebugLevel(ctx context.Context,
// payment request. // payment request.
func (r *rpcServer) DecodePayReq(ctx context.Context, func (r *rpcServer) DecodePayReq(ctx context.Context,
req *lnrpc.PayReqString) (*lnrpc.PayReq, error) { req *lnrpc.PayReqString) (*lnrpc.PayReq, error) {
// Check macaroon to see if this is allowed. // Check macaroon to see if this is allowed.
if r.authSvc != nil { if r.authSvc != nil {
if err := macaroons.ValidateMacaroon(ctx, "decodepayreq", if err := macaroons.ValidateMacaroon(ctx, "decodepayreq",
@ -2578,6 +2628,8 @@ func (r *rpcServer) DecodePayReq(ctx context.Context,
} }
} }
rpcsLog.Tracef("[decodepayreq] decoding: %v", req.PayReq)
// Fist we'll attempt to decode the payment request string, if the // Fist we'll attempt to decode the payment request string, if the
// request is invalid or the checksum doesn't match, then we'll exit // request is invalid or the checksum doesn't match, then we'll exit
// here with an error. // here with an error.

@ -1086,7 +1086,7 @@ type openChanReq struct {
localFundingAmt btcutil.Amount localFundingAmt btcutil.Amount
remoteFundingAmt btcutil.Amount remoteFundingAmt btcutil.Amount
pushAmt btcutil.Amount pushAmt lnwire.MilliSatoshi
// TODO(roasbeef): add ability to specify channel constraints as well // TODO(roasbeef): add ability to specify channel constraints as well
@ -1208,7 +1208,7 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error {
// NOTE: This function is safe for concurrent access. // NOTE: This function is safe for concurrent access.
func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey, func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey,
localAmt btcutil.Amount, localAmt btcutil.Amount,
pushAmt btcutil.Amount) (chan *lnrpc.OpenStatusUpdate, chan error) { pushAmt lnwire.MilliSatoshi) (chan *lnrpc.OpenStatusUpdate, chan error) {
updateChan := make(chan *lnrpc.OpenStatusUpdate, 1) updateChan := make(chan *lnrpc.OpenStatusUpdate, 1)
errChan := make(chan error, 1) errChan := make(chan error, 1)

@ -73,9 +73,9 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
aliceCfg := channeldb.ChannelConfig{ aliceCfg := channeldb.ChannelConfig{
ChannelConstraints: channeldb.ChannelConstraints{ ChannelConstraints: channeldb.ChannelConstraints{
DustLimit: aliceDustLimit, DustLimit: aliceDustLimit,
MaxPendingAmount: btcutil.Amount(rand.Int63()), MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
ChanReserve: btcutil.Amount(rand.Int63()), ChanReserve: btcutil.Amount(rand.Int63()),
MinHTLC: btcutil.Amount(rand.Int63()), MinHTLC: lnwire.MilliSatoshi(rand.Int63()),
MaxAcceptedHtlcs: uint16(rand.Int31()), MaxAcceptedHtlcs: uint16(rand.Int31()),
}, },
CsvDelay: uint16(csvTimeoutAlice), CsvDelay: uint16(csvTimeoutAlice),
@ -87,9 +87,9 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
bobCfg := channeldb.ChannelConfig{ bobCfg := channeldb.ChannelConfig{
ChannelConstraints: channeldb.ChannelConstraints{ ChannelConstraints: channeldb.ChannelConstraints{
DustLimit: bobDustLimit, DustLimit: bobDustLimit,
MaxPendingAmount: btcutil.Amount(rand.Int63()), MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
ChanReserve: btcutil.Amount(rand.Int63()), ChanReserve: btcutil.Amount(rand.Int63()),
MinHTLC: btcutil.Amount(rand.Int63()), MinHTLC: lnwire.MilliSatoshi(rand.Int63()),
MaxAcceptedHtlcs: uint16(rand.Int31()), MaxAcceptedHtlcs: uint16(rand.Int31()),
}, },
CsvDelay: uint16(csvTimeoutBob), CsvDelay: uint16(csvTimeoutBob),
@ -148,8 +148,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
FeePerKw: feePerKw, FeePerKw: feePerKw,
IsInitiator: true, IsInitiator: true,
Capacity: channelCapacity, Capacity: channelCapacity,
LocalBalance: channelBal, LocalBalance: lnwire.NewMSatFromSatoshis(channelBal),
RemoteBalance: channelBal, RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
CommitTx: *aliceCommitTx, CommitTx: *aliceCommitTx,
CommitSig: bytes.Repeat([]byte{1}, 71), CommitSig: bytes.Repeat([]byte{1}, 71),
RemoteCurrentRevocation: bobCommitPoint, RemoteCurrentRevocation: bobCommitPoint,
@ -176,8 +176,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
ChanType: channeldb.SingleFunder, ChanType: channeldb.SingleFunder,
IsInitiator: false, IsInitiator: false,
Capacity: channelCapacity, Capacity: channelCapacity,
LocalBalance: channelBal, LocalBalance: lnwire.NewMSatFromSatoshis(channelBal),
RemoteBalance: channelBal, RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
CommitTx: *bobCommitTx, CommitTx: *bobCommitTx,
CommitSig: bytes.Repeat([]byte{1}, 71), CommitSig: bytes.Repeat([]byte{1}, 71),
RemoteCurrentRevocation: aliceCommitPoint, RemoteCurrentRevocation: aliceCommitPoint,