From 9697d1a49ae7e4045a771a4992fd87436a436a63 Mon Sep 17 00:00:00 2001 From: wuxiaofei Date: Thu, 12 May 2022 18:44:48 +0800 Subject: [PATCH] set usdt-asset use same cfgs(dustlimt/feebase/FeeRate/minhtlc) with btc --- chainreg/chainregistry.go | 20 +- chanacceptor/interface.go | 14 +- chanacceptor/merge.go | 5 +- chanacceptor/rpcacceptor.go | 11 +- channeldb/channel.go | 56 +++- channeldb/graph_cache.go | 1 + .../htlc_incoming_contest_resolver.go | 6 +- contractcourt/interfaces.go | 5 +- discovery/gossiper.go | 3 +- funding/manager.go | 50 ++-- funding/manager_test.go | 94 ++++--- htlcswitch/interfaces.go | 2 +- htlcswitch/link.go | 38 ++- htlcswitch/mock.go | 4 +- htlcswitch/test_utils.go | 29 ++- lnwallet/channel.go | 241 ++++++++++-------- lnwallet/commitment.go | 4 +- lnwallet/errors.go | 8 +- lnwallet/omnicore/op/opreturn.go | 4 +- lnwallet/omnicore/unit.go | 1 + lnwallet/reservation.go | 29 ++- lnwallet/test_utils.go | 33 ++- lnwallet/wallet.go | 4 +- lnwire/accept_channel.go | 21 +- lnwire/msat.go | 26 +- lnwire/open_channel.go | 17 +- peer/brontide.go | 4 +- peer/test_utils.go | 39 +-- routing/pathfind.go | 7 +- routing/pathfind_test.go | 39 +-- routing/payment_session.go | 3 +- routing/router.go | 5 + routing/router_test.go | 46 ++-- routing/unified_policies.go | 9 +- server.go | 13 +- 35 files changed, 570 insertions(+), 321 deletions(-) diff --git a/chainreg/chainregistry.go b/chainreg/chainregistry.go index 6094137a2d..a838849b82 100644 --- a/chainreg/chainregistry.go +++ b/chainreg/chainregistry.go @@ -156,7 +156,7 @@ const ( // DefaultLtcChannelConstraints is the default set of channel constraints that // are meant to be used when initially funding a Litecoin channel. var DefaultLtcChannelConstraints = channeldb.ChannelConstraints{ - DustLimit: DefaultLitecoinDustLimit, + DustLimit: uint64(DefaultLitecoinDustLimit), MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, } @@ -240,7 +240,7 @@ func GenDefaultBtcConstraints() channeldb.ChannelConstraints { dustLimit := lnwallet.DustLimitForSize(input.UnknownWitnessSize) return channeldb.ChannelConstraints{ - DustLimit: dustLimit, + DustLimit: uint64(dustLimit), MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, } } @@ -264,9 +264,11 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { switch cfg.PrimaryChain() { case BitcoinChain: cc.RoutingPolicy = htlcswitch.ForwardingPolicy{ - MinHTLCOut: uint64( cfg.Bitcoin.MinHTLCOut), - BaseFee: cfg.Bitcoin.BaseFee, - FeeRate: cfg.Bitcoin.FeeRate, + Cfg: htlcswitch.ForwardingPolicyCfg{ + MinHTLCOut: cfg.Bitcoin.MinHTLCOut, + BaseFee: cfg.Bitcoin.BaseFee, + FeeRate: cfg.Bitcoin.FeeRate, + }, TimeLockDelta: cfg.Bitcoin.TimeLockDelta, } cc.MinHtlcIn = cfg.Bitcoin.MinHTLCIn @@ -276,9 +278,11 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { ) case LitecoinChain: cc.RoutingPolicy = htlcswitch.ForwardingPolicy{ - MinHTLCOut: uint64(cfg.Litecoin.MinHTLCOut), - BaseFee: cfg.Litecoin.BaseFee, - FeeRate: cfg.Litecoin.FeeRate, + Cfg: htlcswitch.ForwardingPolicyCfg{ + MinHTLCOut: cfg.Litecoin.MinHTLCOut, + BaseFee: cfg.Litecoin.BaseFee, + FeeRate: cfg.Litecoin.FeeRate, + }, TimeLockDelta: cfg.Litecoin.TimeLockDelta, } cc.MinHtlcIn = cfg.Litecoin.MinHTLCIn diff --git a/chanacceptor/interface.go b/chanacceptor/interface.go index 1f0b8cdc3c..f1ff350725 100644 --- a/chanacceptor/interface.go +++ b/chanacceptor/interface.go @@ -4,7 +4,6 @@ import ( "errors" "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/lnwire" ) @@ -46,18 +45,21 @@ type ChannelAcceptResponse struct { // Reserve is the amount that require the remote peer hold in reserve // on the channel. - Reserve btcutil.Amount + //Reserve btcutil.Amount + Reserve uint64 // InFlightTotal is the maximum amount that we allow the remote peer to // hold in outstanding htlcs. - InFlightTotal lnwire.MilliSatoshi + //InFlightTotal lnwire.MilliSatoshi + InFlightTotal uint64 // HtlcLimit is the maximum number of htlcs that we allow the remote // peer to offer us. HtlcLimit uint16 // MinHtlcIn is the minimum incoming htlc value allowed on the channel. - MinHtlcIn lnwire.MilliSatoshi + //MinHtlcIn lnwire.MilliSatoshi + MinHtlcIn uint64 // MinAcceptDepth is the minimum depth that the initiator of the // channel should wait before considering the channel open. @@ -71,8 +73,8 @@ type ChannelAcceptResponse struct { // error. func NewChannelAcceptResponse(accept bool, acceptErr error, upfrontShutdown lnwire.DeliveryAddress, csvDelay, htlcLimit, - minDepth uint16, reserve btcutil.Amount, inFlight, - minHtlcIn lnwire.MilliSatoshi) *ChannelAcceptResponse { + minDepth uint16, reserve uint64, inFlight, + minHtlcIn uint64) *ChannelAcceptResponse { resp := &ChannelAcceptResponse{ UpfrontShutdown: upfrontShutdown, diff --git a/chanacceptor/merge.go b/chanacceptor/merge.go index 852329f5cd..3b19e2efd9 100644 --- a/chanacceptor/merge.go +++ b/chanacceptor/merge.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" - "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/lnwire" ) @@ -48,7 +47,7 @@ func mergeInt64(name string, current, new int64) (int64, error) { // mergeMillisatoshi merges two msat values, failing if they have different // non-zero values. func mergeMillisatoshi(name string, current, - new lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) { + new uint64) (uint64, error) { switch { case current == 0: @@ -123,7 +122,7 @@ func mergeResponse(current, new ChannelAcceptResponse) (ChannelAcceptResponse, if err != nil { return current, err } - current.Reserve = btcutil.Amount(reserve) + current.Reserve = uint64(reserve) current.MinHtlcIn, err = mergeMillisatoshi( fieldMinIn, current.MinHtlcIn, new.MinHtlcIn, diff --git a/chanacceptor/rpcacceptor.go b/chanacceptor/rpcacceptor.go index 5bbcb232a3..bfd93744c5 100644 --- a/chanacceptor/rpcacceptor.go +++ b/chanacceptor/rpcacceptor.go @@ -8,7 +8,6 @@ import ( "time" "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwallet/chancloser" @@ -350,9 +349,9 @@ func (r *RPCAcceptor) sendAcceptRequests(errChan chan error, uint16(resp.CsvDelay), uint16(resp.MaxHtlcCount), uint16(resp.MinAcceptDepth), - btcutil.Amount(resp.ReserveSat), - lnwire.MilliSatoshi(resp.InFlightMaxMsat), - lnwire.MilliSatoshi(resp.MinHtlcIn), + resp.ReserveSat, + resp.InFlightMaxMsat, + resp.MinHtlcIn, ) // Delete the channel from the acceptRequests map. @@ -373,7 +372,7 @@ func (r *RPCAcceptor) sendAcceptRequests(errChan chan error, // validateAcceptorResponse validates the response we get from the channel // acceptor, returning a boolean indicating whether to accept the channel, an // error to send to the peer, and any validation errors that occurred. -func (r *RPCAcceptor) validateAcceptorResponse(dustLimit btcutil.Amount, +func (r *RPCAcceptor) validateAcceptorResponse(dustLimit uint64, req *lnrpc.ChannelAcceptResponse) (bool, error, lnwire.DeliveryAddress, error) { @@ -393,7 +392,7 @@ func (r *RPCAcceptor) validateAcceptorResponse(dustLimit btcutil.Amount, // Ensure that the reserve that has been proposed, if it is set, is at // least the dust limit that was proposed by the remote peer. This is // required by BOLT 2. - reserveSat := btcutil.Amount(req.ReserveSat) + reserveSat := req.ReserveSat if reserveSat != 0 && reserveSat < dustLimit { log.Errorf("Remote reserve: %v sat for channel: %v must be "+ "at least equal to proposed dust limit: %v", diff --git a/channeldb/channel.go b/channeldb/channel.go index 6dab8d4f6c..d75a7aebab 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -312,14 +312,21 @@ func (c ChannelType) HasLeaseExpiration() bool { return c&LeaseExpirationBit == LeaseExpirationBit } -// ChannelConstraints represents a set of constraints meant to allow a node to -// limit their exposure, enact flow control and ensure that all HTLCs are -// economically relevant. This struct will be mirrored for both sides of the -// channel, as each side will enforce various constraints that MUST be adhered -// to for the life time of the channel. The parameters for each of these -// constraints are static for the duration of the channel, meaning the channel -// must be torn down for them to change. -type ChannelConstraints struct { +func (ccc *ChannelConstraints)LoadCfg(assetId uint32){ + + // get usdt value,btc/usdt ~ 30000 + ccc.DustLimit=30* uint64(ccc.Cfg.DustLimit) + ccc.ChanReserve=30* uint64(ccc.Cfg.ChanReserve) + if assetId==omnicore.BtcAssetId{ + ccc.DustLimit=uint64(ccc.Cfg.DustLimit) + ccc.ChanReserve=uint64(ccc.Cfg.ChanReserve) + } + ccc.MaxPendingAmount=lnwire.MstatCfgToI64(assetId,ccc.Cfg.MaxPendingAmount) + ccc.MinHTLC=lnwire.MstatCfgToI64(assetId,ccc.Cfg.MinHTLC) +} + +type ChannelConstraintsCfg struct { + // DustLimit is the threshold (in satoshis) below which any outputs // should be trimmed. When an output is trimmed, it isn't materialized // as an actual output, but is instead burned to miner's fees. @@ -343,6 +350,33 @@ type ChannelConstraints struct { // tandem with the dust limit allows a node to regulate the // smallest HTLC that it deems economically relevant. MinHTLC lnwire.MilliSatoshi +} +type ChannelConstraints struct { + Cfg ChannelConstraintsCfg + + // DustLimit is the threshold (in satoshis) below which any outputs + // should be trimmed. When an output is trimmed, it isn't materialized + // as an actual output, but is instead burned to miner's fees. + DustLimit uint64 + + // ChanReserve is an absolute reservation on the channel for the + // owner of this set of constraints. This means that the current + // settled balance for this node CANNOT dip below the reservation + // amount. This acts as a defense against costless attacks when + // either side no longer has any skin in the game. + ChanReserve uint64 + + // MaxPendingAmount is the maximum pending HTLC value that the + // owner of these constraints can offer the remote node at a + // particular time. + MaxPendingAmount uint64 + + // MinHTLC is the minimum HTLC value that the owner of these + // constraints can offer the remote node. If any HTLCs below this + // amount are offered, then the HTLC will be rejected. This, in + // tandem with the dust limit allows a node to regulate the + // smallest HTLC that it deems economically relevant. + MinHTLC uint64 // MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of // this set of constraints can offer the remote node. This allows each @@ -594,7 +628,7 @@ func (c ChannelStatus) String() string { return statusStr } func (ch *OpenChannel) GetMsgCapForHtlc() uint64{ - if ch.AssetID==1{ + if ch.AssetID==omnicore.BtcAssetId{ return uint64(ch.BtcCapacity)*1000 }else if ch.AssetID>1 { return uint64(ch.AssetCapacity) @@ -602,9 +636,9 @@ func (ch *OpenChannel) GetMsgCapForHtlc() uint64{ return 0 } func (ch *OpenChannel) GetMsgCap() uint64{ - if ch.AssetID==1{ + if ch.AssetID==omnicore.BtcAssetId{ return uint64(ch.BtcCapacity) - }else if ch.AssetID>1{ + }else if ch.AssetID>omnicore.BtcAssetId{ return uint64(ch.AssetCapacity) } return 0 diff --git a/channeldb/graph_cache.go b/channeldb/graph_cache.go index 1aa16e69e6..db893ea41e 100644 --- a/channeldb/graph_cache.go +++ b/channeldb/graph_cache.go @@ -101,6 +101,7 @@ type CachedEdgePolicy struct { func (c *CachedEdgePolicy) ComputeFee( amt uint64) uint64{ + return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts } diff --git a/contractcourt/htlc_incoming_contest_resolver.go b/contractcourt/htlc_incoming_contest_resolver.go index fa7e1d1c37..2bf4153857 100644 --- a/contractcourt/htlc_incoming_contest_resolver.go +++ b/contractcourt/htlc_incoming_contest_resolver.go @@ -234,9 +234,11 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) { HtlcID: h.htlc.HtlcIndex, } + /*obd update wxf + todo check htlcIncomingContestResolver.Resolver*/ resolution, err := h.Registry.NotifyExitHopHtlc( - h.htlc.RHash, h.htlc.BtcAmt, h.htlcExpiry, currentHeight, - circuitKey, hodlChan, payload, + h.htlc.RHash, h.htlc.GetAmt(h.htlc.AssetId), h.htlcExpiry, currentHeight, + circuitKey, hodlChan, payload, h.htlc.AssetId, ) if err != nil { return nil, err diff --git a/contractcourt/interfaces.go b/contractcourt/interfaces.go index ded07f3276..a2ad128bc4 100644 --- a/contractcourt/interfaces.go +++ b/contractcourt/interfaces.go @@ -10,7 +10,6 @@ import ( "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwallet/chainfee" - "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/sweep" ) @@ -25,10 +24,10 @@ type Registry interface { // invoices are never fully settled. The return value describes how the // htlc should be resolved. If the htlc cannot be resolved immediately, // the resolution is sent on the passed in hodlChan later. - NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi, + NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount uint64, expiry uint32, currentHeight int32, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, - payload invoices.Payload) (invoices.HtlcResolution, error) + payload invoices.Payload,assetId uint32) (invoices.HtlcResolution, error) // HodlUnsubscribeAll unsubscribes from all htlc resolutions. HodlUnsubscribeAll(subscriber chan<- interface{}) diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 6fab36f4cd..08e922384c 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -17,6 +17,7 @@ import ( "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/multimutex" "github.com/lightningnetwork/lnd/netann" @@ -1399,7 +1400,7 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { // not already present. edge.MessageFlags |= lnwire.ChanUpdateOptionMaxHtlc amt:=info.Capacity - if info.AssetId==1{ + if info.AssetId==omnicore.BtcAssetId{ amt*=1000 } edge.MaxHTLC = amt diff --git a/funding/manager.go b/funding/manager.go index e086d6de14..2779031452 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -142,10 +142,14 @@ type reservationWithCtx struct { // Constraints we require for the remote. remoteCsvDelay uint16 - remoteMinHtlc lnwire.MilliSatoshi - remoteMaxValue lnwire.MilliSatoshi + //remoteBtcMinHtlc lnwire.MilliSatoshi + //remoteBtcMaxValue lnwire.MilliSatoshi + + remoteMinHtlc uint64 + remoteMaxValue uint64 remoteMaxHtlcs uint16 + // maxLocalCsv is the maximum csv we will accept from the remote. maxLocalCsv uint16 @@ -214,7 +218,8 @@ type InitFundingMsg struct { Private bool // MinHtlcIn is the minimum incoming HTLC that we accept. - MinHtlcIn lnwire.MilliSatoshi + //MinHtlcIn lnwire.MilliSatoshi + MinHtlcIn uint64 // RemoteCsvDelay is the CSV delay we require for the remote peer. RemoteCsvDelay uint16 @@ -230,7 +235,8 @@ type InitFundingMsg struct { // MaxValueInFlight is the maximum amount of coins in MilliSatoshi // that can be pending within the channel. It only applies to the // remote party. - MaxValueInFlight lnwire.MilliSatoshi + //MaxValueInFlight lnwire.MilliSatoshi + MaxValueInFlight uint64 // MaxHtlcs is the maximum number of HTLCs that the remote peer // can offer us. @@ -391,12 +397,12 @@ type Config struct { // channel capacity and dust limit, will return an appropriate amount // for the remote peer's required channel reserve that is to be adhered // to at all times. - RequiredRemoteChanReserve func(capacity, dustLimit btcutil.Amount) btcutil.Amount + RequiredRemoteChanReserve func(capacity, dustLimit uint64) uint64 // RequiredRemoteMaxValue is a function closure that, given the channel // capacity, returns the amount of MilliSatoshis that our remote peer // can have in total outstanding HTLCs with us. - RequiredRemoteMaxValue func(btcutil.Amount) lnwire.MilliSatoshi + RequiredRemoteMaxValue func(assetId uint32, chanAmt uint64) uint64 // RequiredRemoteMaxHTLCs is a function closure that, given the channel // capacity, returns the number of maximum HTLCs the remote peer can @@ -1461,13 +1467,17 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, if msg.DustLimit > maxDustLimit { maxDustLimit = msg.DustLimit } - - chanReserve := f.cfg.RequiredRemoteChanReserve(btcAmt, maxDustLimit) + amt:=uint64(assetAmt) + if msg.AssetId==omnicore.BtcAssetId{ + amt=uint64(btcAmt) + } + chanReserve := f.cfg.RequiredRemoteChanReserve(amt, maxDustLimit) if acceptorResp.Reserve != 0 { chanReserve = acceptorResp.Reserve } - remoteMaxValue := f.cfg.RequiredRemoteMaxValue(btcAmt) + /*obd update wxf*/ + remoteMaxValue := f.cfg.RequiredRemoteMaxValue(msg.AssetId, amt) if acceptorResp.InFlightTotal != 0 { remoteMaxValue = acceptorResp.InFlightTotal } @@ -1479,7 +1489,7 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, // Default to our default minimum hltc value, replacing it with the // channel acceptor's value if it is set. - minHtlc := f.cfg.DefaultMinHtlcIn + minHtlc := lnwire.MstatCfgToI64(msg.AssetId, f.cfg.DefaultMinHtlcIn) if acceptorResp.MinHtlcIn != 0 { minHtlc = acceptorResp.MinHtlcIn } @@ -1498,7 +1508,6 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, assetId: assetId, remoteCsvDelay: remoteCsvDelay, remoteMinHtlc: minHtlc, - remoteMaxValue: remoteMaxValue, remoteMaxHtlcs: maxHtlcs, maxLocalCsv: f.cfg.MaxLocalCSVDelay, channelType: msg.ChannelType, @@ -1708,12 +1717,16 @@ func (f *Manager) handleFundingAccept(peer lnpeer.Peer, return } + amt:=uint64(resCtx.chanAssetAmt) + if resCtx.assetId==omnicore.BtcAssetId{ + amt=uint64(resCtx.chanBtcAmt) + } // As they've accepted our channel constraints, we'll regenerate them // here so we can properly commit their accepted constraints to the // reservation. Also make sure that we re-generate the ChannelReserve // with our dust limit or we can get stuck channels. chanReserve := f.cfg.RequiredRemoteChanReserve( - resCtx.chanBtcAmt, resCtx.reservation.OurContribution().DustLimit, + amt, resCtx.reservation.OurContribution().DustLimit, ) // The remote node has responded with their portion of the channel @@ -3403,6 +3416,13 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { log.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID, int64(commitFeePerKw)) + amt:=uint64(assetCapacity) + if msg.AssetId==omnicore.BtcAssetId{ + amt=uint64(btcCapacity) + } + + /*obd update wxf + todo asset delay */ // If the remote CSV delay was not set in the open channel request, // we'll use the RequiredRemoteDelay closure to compute the delay we // require given the total amount of funds within the channel. @@ -3412,12 +3432,12 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { // If no minimum HTLC value was specified, use the default one. if minHtlcIn == 0 { - minHtlcIn = f.cfg.DefaultMinHtlcIn + minHtlcIn = lnwire.MstatCfgToI64(msg.AssetId, f.cfg.DefaultMinHtlcIn) } // If no max value was specified, use the default one. if maxValue == 0 { - maxValue = f.cfg.RequiredRemoteMaxValue(btcCapacity) + maxValue = f.cfg.RequiredRemoteMaxValue(msg.AssetId, amt) } if maxHtlcs == 0 { @@ -3468,7 +3488,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { // Finally, we'll use the current value of the channels and our default // policy to determine of required commitment constraints for the // remote party. - chanReserve := f.cfg.RequiredRemoteChanReserve(btcCapacity, ourDustLimit) + chanReserve := f.cfg.RequiredRemoteChanReserve(amt, ourDustLimit) // When opening a script enforced channel lease, include the required // expiry TLV record in our proposal. diff --git a/funding/manager_test.go b/funding/manager_test.go index d89b085ee6..75820e7241 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -413,7 +413,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, return 4 }, RequiredRemoteChanReserve: func(chanAmt, - dustLimit btcutil.Amount) btcutil.Amount { + dustLimit uint64) uint64 { reserve := chanAmt / 100 if reserve < dustLimit { @@ -422,9 +422,15 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, return reserve }, - RequiredRemoteMaxValue: func(chanAmt btcutil.Amount) lnwire.MilliSatoshi { - reserve := lnwire.NewMSatFromSatoshis(chanAmt / 100) - return lnwire.NewMSatFromSatoshis(chanAmt) - reserve + RequiredRemoteMaxValue: func(assetId uint32, chanAmt uint64) uint64 { + // By default, we'll allow the remote peer to fully + // utilize the full bandwidth of the channel, minus our + // required reserve. + if assetId==omnicore.BtcAssetId { + reserve := lnwire.NewMSatFromSatoshis(btcutil.Amount(chanAmt) / 100) + return uint64(lnwire.NewMSatFromSatoshis(btcutil.Amount(chanAmt)) - reserve) + } + return chanAmt-chanAmt / 100 }, RequiredRemoteMaxHTLCs: func(chanAmt btcutil.Amount) uint16 { return uint16(input.MaxHTLCNumber / 2) @@ -658,7 +664,7 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt, ) fundingOutPoint := &wire.OutPoint{ Hash: publ.TxHash(), - Index: 0, + Index: 1, } return fundingOutPoint, publ } @@ -766,7 +772,6 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt, case <-time.After(time.Second * 5): t.Fatalf("alice did not publish funding tx") } - t.Log(1234) // Make sure the notification about the pending channel was sent out. select { case <-alice.mockChanEvent.pendingOpenEvent: @@ -778,12 +783,10 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt, case <-time.After(time.Second * 5): t.Fatalf("bob did not send pending channel event") } - t.Log(12345) // Finally, make sure neither have active reservation for the channel // now pending open in the database. assertNumPendingReservations(t, alice, bobPubKey, 0) assertNumPendingReservations(t, bob, alicePubKey, 0) - t.Log(123456) return publ } @@ -967,12 +970,14 @@ func assertMarkedOpen(t *testing.T, alice, bob *testNode, case <-time.After(time.Second * 5): t.Fatalf("alice did not send open channel event") } + var po wire.OutPoint select { - case <-bob.mockChanEvent.openEvent: + case po = <-bob.mockChanEvent.openEvent: case <-time.After(time.Second * 5): t.Fatalf("bob did not send open channel event") } - + //t.Log("fundingOutPoint :",fundingOutPoint) + t.Log("fundingOutPoint open event:",po) assertDatabaseState(t, alice, fundingOutPoint, markedOpen) assertDatabaseState(t, bob, fundingOutPoint, markedOpen) } @@ -1000,9 +1005,9 @@ func assertAddedToRouterGraph(t *testing.T, alice, bob *testNode, // advertise the value required by Bob and vice versa. If they are not set the // advertised value will be checked against the other node's default min_htlc // value. -func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, - capacity btcutil.Amount, customMinHtlc []lnwire.MilliSatoshi, - customMaxHtlc []lnwire.MilliSatoshi) { +func assertChannelAnnouncements(t *testing.T, assetId uint32, alice, bob *testNode, + capacity uint64, customMinHtlc []uint64, + customMaxHtlc []uint64) { t.Helper() // After the FundingLocked message is sent, Alice and Bob will each @@ -1035,8 +1040,8 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, // advertise the MinHTLC value required by the // _other_ node. other := (j + 1) % 2 - minHtlc := nodes[other].fundingMgr.cfg. - DefaultMinHtlcIn + minHtlc :=lnwire.MstatCfgToI64(assetId, nodes[other].fundingMgr.cfg. + DefaultMinHtlcIn) // We might expect a custom MinHTLC value. if len(customMinHtlc) > 0 { @@ -1056,7 +1061,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, } maxHtlc := alice.fundingMgr.cfg.RequiredRemoteMaxValue( - capacity, + assetId, capacity, ) // We might expect a custom MaxHltc value. if len(customMaxHtlc) > 0 { @@ -1225,7 +1230,7 @@ func TestFundingManagerNormalWorkflow(t *testing.T) { // transaction is broadcasted. localAmt := btcutil.Amount(500000) pushAmt := btcutil.Amount(0) - localAssetAmt := omnicore.Amount(500000) + localAssetAmt := omnicore.Amount(10000) pushAssetAmt := omnicore.Amount(0) assetId:=uint32(31) capacity := localAmt + pushAmt @@ -1267,7 +1272,11 @@ func TestFundingManagerNormalWorkflow(t *testing.T) { // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + cap:=uint64(capacity) + if assetId>1{ + cap=uint64(localAssetAmt) + } + assertChannelAnnouncements(t,assetId, alice, bob, cap, nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -1577,7 +1586,7 @@ func TestFundingManagerRestartBehavior(t *testing.T) { // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, uint64(capacity), nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -1716,9 +1725,12 @@ func TestFundingManagerOfflinePeer(t *testing.T) { // The state should now be fundingLockedSent assertDatabaseState(t, alice, fundingOutPoint, fundingLockedSent) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -2130,9 +2142,12 @@ func TestFundingManagerReceiveFundingLockedTwice(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -2234,9 +2249,12 @@ func TestFundingManagerRestartAfterChanAnn(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -2336,9 +2354,12 @@ func TestFundingManagerRestartAfterReceivingFundingLocked(t *testing.T) { // At this point we restart Alice's fundingManager. recreateAliceFundingManager(t, alice) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) @@ -2408,9 +2429,12 @@ func TestFundingManagerPrivateChannel(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update @@ -2522,9 +2546,12 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) // Make sure both fundingManagers send the expected channel // announcements. - assertChannelAnnouncements(t, alice, bob, capacity, nil, nil) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, nil, nil) // Note: We don't check for the addedToRouterGraph state because in // the private channel mode, the state is quickly changed from @@ -2712,7 +2739,9 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) { } reserve := lnwire.NewMSatFromSatoshis(fundingAmt / 100) - maxValueAcceptChannel := lnwire.NewMSatFromSatoshis(fundingAmt) - reserve + /*obd update wxf + todo check asset*/ + maxValueAcceptChannel := uint64(lnwire.NewMSatFromSatoshis(fundingAmt) - reserve) if acceptChannelResponse.MaxValueInFlight != maxValueAcceptChannel { t.Fatalf("expected AcceptChannel to have MaxValueInFlight %v, got %v", @@ -2748,7 +2777,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) { // Helper method for checking the MinHtlc value stored for a // reservation. assertMinHtlc := func(resCtx *reservationWithCtx, - expOurMinHtlc, expTheirMinHtlc lnwire.MilliSatoshi) error { + expOurMinHtlc, expTheirMinHtlc uint64) error { ourMinHtlc := resCtx.reservation.OurContribution().MinHTLC if ourMinHtlc != expOurMinHtlc { @@ -2767,7 +2796,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) { // Helper method for checking the MaxValueInFlight stored for a // reservation. assertMaxHtlc := func(resCtx *reservationWithCtx, - expOurMaxValue, expTheirMaxValue lnwire.MilliSatoshi) error { + expOurMaxValue, expTheirMaxValue uint64) error { ourMaxValue := resCtx.reservation.OurContribution().MaxPendingAmount @@ -2888,14 +2917,17 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) { // Alice should advertise the default MinHTLC value of // 5, while bob should advertise the value minHtlc, since Alice // required him to use it. - minHtlcArr := []lnwire.MilliSatoshi{5, minHtlcIn} + minHtlcArr := []uint64{5, minHtlcIn} // For maxHltc Alice should advertise the default MaxHtlc value of // maxValueAcceptChannel, while bob should advertise the value // maxValueInFlight since Alice required him to use it. - maxHtlcArr := []lnwire.MilliSatoshi{maxValueAcceptChannel, maxValueInFlight} + maxHtlcArr := []uint64{maxValueAcceptChannel, maxValueInFlight} - assertChannelAnnouncements(t, alice, bob, capacity, minHtlcArr, maxHtlcArr) + /*obd update wxf + todo check asset cap*/ + cap:=uint64(capacity) + assertChannelAnnouncements(t, omnicore.BtcAssetId, alice, bob, cap, minHtlcArr, maxHtlcArr) // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index 4e30f1bd8c..fbefb1d487 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -29,7 +29,7 @@ type InvoiceDatabase interface { NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount uint64, expiry uint32, currentHeight int32, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, - payload invoices.Payload) (invoices.HtlcResolution, error) + payload invoices.Payload, assetId uint32) (invoices.HtlcResolution, error) // CancelInvoice attempts to cancel the invoice corresponding to the // passed payment hash. diff --git a/htlcswitch/link.go b/htlcswitch/link.go index d5f325d169..b662751473 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -61,6 +61,33 @@ const ( DefaultMaxLinkFeeAllocation float64 = 0.5 ) +func (fwdp *ForwardingPolicy)LoadCfg(assetId uint32) { + fwdp.MinHTLCOut =lnwire.MstatCfgToI64(assetId,fwdp.Cfg.MinHTLCOut) + fwdp.BaseFee =lnwire.MstatCfgToI64(assetId,fwdp.Cfg.BaseFee) + fwdp.FeeRate =uint64(fwdp.Cfg.FeeRate) + +} + +/*obd udpate wxf +default config +*/ +type ForwardingPolicyCfg struct { + // MinHTLC is the smallest HTLC that is to be forwarded. + MinHTLCOut lnwire.MilliSatoshi + + //// MaxHTLC is the largest HTLC that is to be forwarded. + //MaxHTLC lnwire.MilliSatoshi + + // BaseFee is the base fee, expressed in milli-satoshi that must be + // paid for each incoming HTLC. This field, combined with FeeRate is + // used to compute the required fee for a given HTLC. + BaseFee lnwire.MilliSatoshi + + // FeeRate is the fee rate, expressed in milli-satoshi that must be + // paid for each incoming HTLC. This field combined with BaseFee is + // used to compute the required fee for a given HTLC. + FeeRate lnwire.MilliSatoshi +} // ForwardingPolicy describes the set of constraints that a given ChannelLink // is to adhere to when forwarding HTLC's. For each incoming HTLC, this set of // constraints will be consulted in order to ensure that adequate fees are @@ -69,6 +96,11 @@ const ( // the error possibly carrying along a ChannelUpdate message that includes the // latest policy. type ForwardingPolicy struct { + /*obd udpate wxf + default config + */ + Cfg ForwardingPolicyCfg + // MinHTLC is the smallest HTLC that is to be forwarded. MinHTLCOut uint64 @@ -78,12 +110,12 @@ type ForwardingPolicy struct { // BaseFee is the base fee, expressed in milli-satoshi that must be // paid for each incoming HTLC. This field, combined with FeeRate is // used to compute the required fee for a given HTLC. - BaseFee lnwire.MilliSatoshi + BaseFee uint64 // FeeRate is the fee rate, expressed in milli-satoshi that must be // paid for each incoming HTLC. This field combined with BaseFee is // used to compute the required fee for a given HTLC. - FeeRate lnwire.MilliSatoshi + FeeRate uint64 // TimeLockDelta is the absolute time-lock value, expressed in blocks, // that will be subtracted from an incoming HTLC's timelock value to @@ -3076,7 +3108,7 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor, event, err := l.cfg.Registry.NotifyExitHopHtlc( invoiceHash, pd.GetMsgAmt(), pd.Timeout, int32(heightNow), - circuitKey, l.hodlQueue.ChanIn(), payload, + circuitKey, l.hodlQueue.ChanIn(), payload, pd.AssetID, ) if err != nil { return err diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index b0ccd32692..7c34f7a251 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -878,11 +878,11 @@ func (i *mockInvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash, amt uint64, expiry uint32, currentHeight int32, circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, - payload invoices.Payload) (invoices.HtlcResolution, error) { + payload invoices.Payload,assetId uint32) (invoices.HtlcResolution, error) { event, err := i.registry.NotifyExitHopHtlc( rhash, amt, expiry, currentHeight, circuitKey, hodlChan, - payload,31, + payload,assetId, ) if err != nil { return nil, err diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index 86d1f08da1..8c0d9e879e 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -127,7 +127,7 @@ type testLightningChannel struct { func createTestChannel(alicePrivKey, bobPrivKey []byte, aliceAmount, bobAmount, aliceReserve, bobReserve btcutil.Amount, aliceAssetAmount, bobAssetAmount, aliceAssetReserve, bobAssetReserve omnicore.Amount, - chanID lnwire.ShortChannelID) (*testLightningChannel, + chanID lnwire.ShortChannelID,assetId uint32) (*testLightningChannel, *testLightningChannel, func(), error) { aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(), alicePrivKey) @@ -138,21 +138,24 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, csvTimeoutBob := uint32(4) isAliceInitiator := true + maxAmt:=uint64(channelCapacity) + if assetId==omnicore.BtcAssetId{ + maxAmt=uint64(lnwire.NewMSatFromSatoshis( + channelCapacity)) + } aliceConstraints := &channeldb.ChannelConstraints{ - DustLimit: btcutil.Amount(200), - MaxPendingAmount: lnwire.NewMSatFromSatoshis( - channelCapacity), - ChanReserve: aliceReserve, + DustLimit: uint64(btcutil.Amount(200)), + MaxPendingAmount: maxAmt, + ChanReserve: uint64(aliceReserve), MinHTLC: 0, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutAlice), } bobConstraints := &channeldb.ChannelConstraints{ - DustLimit: btcutil.Amount(800), - MaxPendingAmount: lnwire.NewMSatFromSatoshis( - channelCapacity), - ChanReserve: bobReserve, + DustLimit: uint64(btcutil.Amount(800)), + MaxPendingAmount: maxAmt, + ChanReserve: uint64(bobReserve), MinHTLC: 0, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutBob), @@ -888,7 +891,7 @@ func createClusterChannels(aliceToBob, bobToCarol btcutil.Amount) ( createTestChannel(alicePrivKey, bobPrivKey, aliceToBob, aliceToBob, 0, 0, 0,0,0,0, - firstChanID) + firstChanID,omnicore.BtcAssetId) if err != nil { return nil, nil, nil, errors.Errorf("unable to create "+ "alice<->bob channel: %v", err) @@ -898,7 +901,7 @@ func createClusterChannels(aliceToBob, bobToCarol btcutil.Amount) ( createTestChannel(bobPrivKey, carolPrivKey, bobToCarol, bobToCarol, 0, 0, 0,0,0,0, - secondChanID) + secondChanID,omnicore.BtcAssetId) if err != nil { cleanAliceBob() return nil, nil, nil, errors.Errorf("unable to create "+ @@ -1089,7 +1092,7 @@ func createTwoClusterChannels(aliceToBob, bobToCarol btcutil.Amount) ( createTestChannel(alicePrivKey, bobPrivKey, aliceToBob, aliceToBob, 0, 0, 0,0,0,0, - firstChanID) + firstChanID,omnicore.BtcAssetId) if err != nil { return nil, nil, nil, errors.Errorf("unable to create "+ "alice<->bob channel: %v", err) @@ -1112,7 +1115,7 @@ func newHopNetwork() *hopNetwork { globalPolicy := ForwardingPolicy{ MinHTLCOut: uint64( lnwire.NewMSatFromSatoshis(5)), - BaseFee: lnwire.NewMSatFromSatoshis(1), + BaseFee: uint64(lnwire.NewMSatFromSatoshis(1)), TimeLockDelta: defaultDelta, } obfuscator := NewMockObfuscator() diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 59efd00519..f8aa7841f4 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -219,7 +219,7 @@ func (pd *PaymentDescriptor)GetMsgAmt() uint64{ return uint64(pd.BtcAmount) } func (pd *PaymentDescriptor)SetAmtFromHtlcMsg(htlc *lnwire.UpdateAddHTLC){ - if htlc.AssetID==1{ + if htlc.AssetID==omnicore.BtcAssetId{ pd.BtcAmount=lnwire.MilliSatoshi(htlc.Amount) }else{ pd.AssetAmount=omnicore.Amount(htlc.Amount) @@ -549,7 +549,8 @@ type commitment struct { // dustLimit is the limit on the commitment transaction such that no // output values should be below this amount. - dustLimit btcutil.Amount + //dustLimit btcutil.Amount + dustLimit uint64 // outgoingHTLCs is a slice of all the outgoing HTLC's (from our PoV) // on this commitment transaction. @@ -2445,9 +2446,11 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, ourAmt := revokedSnapshot.LocalBtcBalance.ToSatoshis() theirAmt := revokedSnapshot.RemoteBtcBalance.ToSatoshis() + /*obd updte wxf + todo check asset*/ // If our balance exceeds the remote party's dust limit, instantiate // the sign descriptor for our output. - if ourAmt >= chanState.RemoteChanCfg.DustLimit { + //if ourAmt >= chanState.RemoteChanCfg.DustLimit { ourSignDesc = &input.SignDescriptor{ SingleTweak: keyRing.LocalCommitKeyTweak, KeyDesc: chanState.LocalChanCfg.PaymentBasePoint, @@ -2458,11 +2461,11 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, }, HashType: txscript.SigHashAll, } - } + //} // Similarly, if their balance exceeds the remote party's dust limit, // assemble the sign descriptor for their output, which we can sweep. - if theirAmt >= chanState.RemoteChanCfg.DustLimit { + //if theirAmt >= chanState.RemoteChanCfg.DustLimit { theirSignDesc = &input.SignDescriptor{ KeyDesc: chanState.LocalChanCfg.RevocationBasePoint, DoubleTweak: commitmentSecret, @@ -2473,7 +2476,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, }, HashType: txscript.SigHashAll, } - } + //} // With the commitment outputs located, we'll now generate all the // retribution structs for each of the HTLC transactions active on the @@ -2565,50 +2568,46 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, func HtlcIsDust(chanType channeldb.ChannelType, incoming, ourCommit bool, feePerKw chainfee.SatPerKWeight, htlcAmt, dustLimit uint64, assetId uint32) bool { - /*obd update wxf - todo add asset dustLimit - */ - if assetId>1{ - return false - //return htlcAmt0 && predictOurAdd.AssetID==1{ + if predictOurAdd != nil && predictOurAdd.AssetAmount > 0 && predictOurAdd.AssetID == omnicore.BtcAssetId { return fmt.Errorf("LightningChannel validateCommitmentSanity predictOurAdd err: miss AssetID") } /* obd add wxf todo check Asset */ - if predictOurAdd!=nil && predictOurAdd.AssetID>1{ + if predictOurAdd != nil && predictOurAdd.AssetID !=omnicore.BtcAssetId { return nil } - if predictTheirAdd!=nil && predictTheirAdd.AssetID>1{ + if predictTheirAdd != nil && predictTheirAdd.AssetID !=omnicore.BtcAssetId { return nil } - - if predictTheirAdd!=nil && predictTheirAdd.AssetAmount>0 && predictTheirAdd.AssetID==1{ + if predictTheirAdd != nil && predictTheirAdd.AssetAmount > 0 && predictTheirAdd.AssetID == omnicore.BtcAssetId { return fmt.Errorf("LightningChannel validateCommitmentSanity predictTheirAdd err: miss AssetID") } @@ -3548,8 +3546,13 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter, if remoteChain { commitChain = lc.remoteCommitChain } - ourInitialBalance := commitChain.tip().ourBtcBalance - theirInitialBalance := commitChain.tip().theirBtcBalance + + ourInitialBalance := uint64(commitChain.tip().ourAssetBalance) + theirInitialBalance := uint64(commitChain.tip().theirAssetBalance) + if lc.channelState.AssetID == omnicore.BtcAssetId { + ourInitialBalance = uint64(commitChain.tip().ourBtcBalance) + theirInitialBalance = uint64(commitChain.tip().theirBtcBalance) + } /* bod update wxf @@ -3558,7 +3561,7 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter, //ourBtcBalance, theirBtcBalance,ourAssetBalance, theirAssetBalance, commitWeight, filteredView, err := lc.computeView( // view, remoteChain, false, //) - ourBtcBalance, theirBtcBalance,_, _, commitWeight, filteredView, err := lc.computeView( + ourBtcBalance, theirBtcBalance,ourAssetBalance, theirAssetBalance, commitWeight, filteredView, err := lc.computeView( view, remoteChain, false, ) if err != nil { @@ -3594,17 +3597,23 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter, feePerKw, chainfee.FeePerKwFloor) } + ourAmt:=uint64(ourAssetBalance) + if lc.channelState.AssetID==omnicore.BtcAssetId{ + ourAmt=uint64(ourBtcBalance) + } + thireAmt:=uint64(theirAssetBalance) + if lc.channelState.AssetID==omnicore.BtcAssetId{ + thireAmt=uint64(theirBtcBalance) + } // If the added HTLCs will decrease the balance, make sure they won't // dip the local and remote balances below the channel reserves. switch { - case ourBtcBalance < ourInitialBalance && - ourBtcBalance < lnwire.NewMSatFromSatoshis( - lc.channelState.LocalChanCfg.ChanReserve): + case ourAmt < ourInitialBalance && + ourAmt < lc.channelState.LocalChanCfg.ChanReserve: return ErrBelowChanReserve - case theirBtcBalance < theirInitialBalance && - theirBtcBalance < lnwire.NewMSatFromSatoshis( - lc.channelState.RemoteChanCfg.ChanReserve): + case thireAmt < theirInitialBalance && + thireAmt = nonDustHtlcAmt { - ourBalance = nonDustHtlcAmt - 1 + // If they cannot pay the fee if we add another non-dust HTLC, we'll + // report our available balance just below the non-dust amount, to + // avoid attempting HTLCs larger than this size. + if theirAmt < uint64(htlcCommitFee) && ourAmt >=nonDustHtlcAmt { + ourAmt = nonDustHtlcAmt - 1 + } } - return uint64(ourBalance), commitWeight + return uint64(ourAmt), commitWeight } // StateSnapshot returns a snapshot of the current fully committed state within @@ -7231,6 +7267,9 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd return revocationMsg, nil } + +/*obd update wxf +todo check asset*/ // CreateCooperativeCloseTx creates a transaction which if signed by both // parties, then broadcast cooperatively closes an active channel. The creation // of the closure transaction is modified by a boolean indicating if the party @@ -7238,7 +7277,7 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd // expected that the initiator pays the transaction fees for the closing // transaction in full. func CreateCooperativeCloseTx(fundingTxIn wire.TxIn, - localDust, remoteDust, ourBalance, theirBalance btcutil.Amount, + localDust, remoteDust, ourBalance, theirBalance uint64, ourDeliveryScript, theirDeliveryScript []byte) *wire.MsgTx { // Construct the transaction to perform a cooperative closure of the @@ -7471,7 +7510,7 @@ func (lc *LightningChannel) ActiveHtlcs() []channeldb.HTLC { } // LocalChanReserve returns our local ChanReserve requirement for the remote party. -func (lc *LightningChannel) LocalChanReserve() btcutil.Amount { +func (lc *LightningChannel) LocalChanReserve() uint64 { return lc.channelState.LocalChanCfg.ChanReserve } @@ -7488,7 +7527,7 @@ func (lc *LightningChannel) NextLocalHtlcIndex() (uint64, error) { // FwdMinHtlc returns the minimum HTLC value required by the remote node, i.e. // the minimum value HTLC we can forward on this channel. -func (lc *LightningChannel) FwdMinHtlc() lnwire.MilliSatoshi { +func (lc *LightningChannel) FwdMinHtlc() uint64 { return lc.channelState.LocalChanCfg.MinHTLC } diff --git a/lnwallet/commitment.go b/lnwallet/commitment.go index fb97b8acc3..4c340c5b5b 100644 --- a/lnwallet/commitment.go +++ b/lnwallet/commitment.go @@ -814,7 +814,7 @@ func CreateCommitTx(chanType channeldb.ChannelType, commitTx.AddTxIn(&fundingOutput) // Avoid creating dust outputs within the commitment transaction. - localOutput := btcAmountToLocal >= localChanCfg.DustLimit + localOutput :=uint64(btcAmountToLocal) >= localChanCfg.DustLimit /* obd add wxf */ @@ -833,7 +833,7 @@ func CreateCommitTx(chanType channeldb.ChannelType, opAmounts.Add(toLocalScript.PkScript,assetAmountToLocal) } - remoteOutput := btcAmountToRemote >= localChanCfg.DustLimit + remoteOutput := uint64(btcAmountToRemote) >= localChanCfg.DustLimit /* obd add wxf */ diff --git a/lnwallet/errors.go b/lnwallet/errors.go index 0526acffda..f63aad6848 100644 --- a/lnwallet/errors.go +++ b/lnwallet/errors.go @@ -61,7 +61,7 @@ func ErrCsvDelayTooLarge(remoteDelay, maxDelay uint16) ReservationError { // ErrChanReserveTooSmall returns an error indicating that the channel reserve // the remote is requiring is too small to be accepted. -func ErrChanReserveTooSmall(reserve, dustLimit btcutil.Amount) ReservationError { +func ErrChanReserveTooSmall(reserve, dustLimit uint64) ReservationError { return ReservationError{ fmt.Errorf("channel reserve of %v sat is too small, min is %v "+ "sat", int64(reserve), int64(dustLimit)), @@ -88,7 +88,7 @@ func ErrNonZeroPushAmount() ReservationError { // ErrMinHtlcTooLarge returns an error indicating that the MinHTLC value the // remote required is too large to be accepted. func ErrMinHtlcTooLarge(minHtlc, - maxMinHtlc lnwire.MilliSatoshi) ReservationError { + maxMinHtlc uint64) ReservationError { return ReservationError{ fmt.Errorf("minimum HTLC value is too large: %v, max is %v", minHtlc, maxMinHtlc), @@ -116,7 +116,7 @@ func ErrMaxHtlcNumTooSmall(maxHtlc, minMaxHtlc uint16) ReservationError { // ErrMaxValueInFlightTooSmall returns an error indicating that the 'max HTLC // value in flight' the remote required is too small to be accepted. func ErrMaxValueInFlightTooSmall(maxValInFlight, - minMaxValInFlight lnwire.MilliSatoshi) ReservationError { + minMaxValInFlight uint64) ReservationError { return ReservationError{ fmt.Errorf("maxValueInFlight too small: %v, min is %v", maxValInFlight, minMaxValInFlight), @@ -154,7 +154,7 @@ func ErrChanTooLarge(chanSize, maxChanSize btcutil.Amount) ReservationError { // ErrInvalidDustLimit returns an error indicating that a proposed DustLimit // was rejected. -func ErrInvalidDustLimit(dustLimit btcutil.Amount) ReservationError { +func ErrInvalidDustLimit(dustLimit uint64) ReservationError { return ReservationError{ fmt.Errorf("dust limit %v is invalid", dustLimit), } diff --git a/lnwallet/omnicore/op/opreturn.go b/lnwallet/omnicore/op/opreturn.go index f80a3cb97b..b21ea3539c 100644 --- a/lnwallet/omnicore/op/opreturn.go +++ b/lnwallet/omnicore/op/opreturn.go @@ -142,13 +142,13 @@ func (p *PksAmounts)Len()int { return len(p.pksAmounts) } func (p *PksAmounts)Add(pks []byte, amount omnicore.Amount){ - if p.assetID==0 || p.assetID==1 { + if p.assetID==0 || p.assetID==omnicore.BtcAssetId { panic(fmt.Errorf("miss assetId")) } p.pksAmounts=append(p.pksAmounts,&pksAmount{pks,amount}) } func AddOpReturnToTx(tx *wire.MsgTx ,p *PksAmounts )error{ - if p.assetID==0 || p.assetID==1{ + if p.assetID==0 || p.assetID==omnicore.BtcAssetId{ return fmt.Errorf("miss assetId") } opOutPuts:=[]*Output{} diff --git a/lnwallet/omnicore/unit.go b/lnwallet/omnicore/unit.go index ff7d8e6777..77b8a4de38 100644 --- a/lnwallet/omnicore/unit.go +++ b/lnwallet/omnicore/unit.go @@ -133,3 +133,4 @@ func (a Amount) MulF64(f float64) Amount { const OmniGas= btcutil.Amount(546) +const BtcAssetId= 1 diff --git a/lnwallet/reservation.go b/lnwallet/reservation.go index 32b8f29173..8bf79d28ad 100644 --- a/lnwallet/reservation.go +++ b/lnwallet/reservation.go @@ -246,8 +246,10 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount, feeMSat += 2 * lnwire.NewMSatFromSatoshis(anchorSize) } + /*obd update wxf + todo use asset dust*/ // Used to cut down on verbosity. - defaultDust := wallet.Cfg.DefaultConstraints.DustLimit + defaultDust := wallet.Cfg.DefaultConstraints.Cfg.DustLimit // If we're the responder to a single-funder reservation, then we have // no initial balance in the channel unless the remote party is pushing @@ -476,18 +478,21 @@ func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints, return ErrChanReserveTooSmall(c.ChanReserve, c.DustLimit) } - // Validate against the maximum-sized witness script dust limit, and - // also ensure that the DustLimit is not too large. - maxWitnessLimit := DustLimitForSize(input.UnknownWitnessSize) - if c.DustLimit < maxWitnessLimit || c.DustLimit > 3*maxWitnessLimit { - return ErrInvalidDustLimit(c.DustLimit) - } + if r.partialState.AssetID==omnicore.BtcAssetId{ + btcDustLimt:=btcutil.Amount(c.DustLimit) + // Validate against the maximum-sized witness script dust limit, and + // also ensure that the DustLimit is not too large. + maxWitnessLimit := DustLimitForSize(input.UnknownWitnessSize) + if btcDustLimt < maxWitnessLimit || btcDustLimt > 3*maxWitnessLimit { + return ErrInvalidDustLimit(c.DustLimit) + } - // Fail if we consider the channel reserve to be too large. We - // currently fail if it is greater than 20% of the channel capacity. - maxChanReserve := r.partialState.BtcCapacity / 5 - if c.ChanReserve > maxChanReserve { - return ErrChanReserveTooLarge(c.ChanReserve, maxChanReserve) + // Fail if we consider the channel reserve to be too large. We + // currently fail if it is greater than 20% of the channel capacity. + maxChanReserve := r.partialState.BtcCapacity / 5 + if btcutil.Amount(c.ChanReserve) > maxChanReserve { + return ErrChanReserveTooLarge(btcutil.Amount(c.ChanReserve), maxChanReserve) + } } // Fail if the minimum HTLC value is too large. If this is too large, diff --git a/lnwallet/test_utils.go b/lnwallet/test_utils.go index f41221fe50..450d30daeb 100644 --- a/lnwallet/test_utils.go +++ b/lnwallet/test_utils.go @@ -103,7 +103,8 @@ var ( */ //testChannelCapacity float64 = 10 testChannelBtcCapacity float64 = 10 - testChannelAssetCapacity float64 = 10 + testChannelAssetCapacity float64 = 10*30000 + testAssetId=uint32(31) ) // CreateTestChannels creates to fully populated channels to be used within @@ -161,12 +162,16 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( bobKeys = append(bobKeys, bobKey) } + /*obd update wxf + todo add asset ChannelConstraints*/ aliceCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ - DustLimit: aliceDustLimit, - MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelBtcCapacity), - ChanReserve: channelBtcCapacity / 100, - MinHTLC: 0, + Cfg: channeldb.ChannelConstraintsCfg{ + DustLimit: aliceDustLimit, + MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelBtcCapacity), + ChanReserve: channelBtcCapacity / 100, + MinHTLC: 0, + }, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutAlice), }, @@ -186,12 +191,15 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( PubKey: aliceKeys[4].PubKey(), }, } + (&aliceCfg.ChannelConstraints).LoadCfg(testAssetId) bobCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ - DustLimit: bobDustLimit, - MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelBtcCapacity), - ChanReserve: channelBtcCapacity / 100, - MinHTLC: 0, + Cfg: channeldb.ChannelConstraintsCfg{ + DustLimit: bobDustLimit, + MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelBtcCapacity), + ChanReserve: channelBtcCapacity / 100, + MinHTLC: 0, + }, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, CsvDelay: uint16(csvTimeoutBob), }, @@ -211,6 +219,7 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( PubKey: bobKeys[4].PubKey(), }, } + (&bobCfg.ChannelConstraints).LoadCfg(testAssetId) bobRoot, err := chainhash.NewHash(bobKeys[0].Serialize()) if err != nil { @@ -236,7 +245,7 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( aliceCommitTx, bobCommitTx, err := CreateCommitmentTxns( channelBtcBal, channelBtcBal,channelAssetCapacity, 0, &aliceCfg, &bobCfg, aliceCommitPoint, - bobCommitPoint, *fundingTxIn, chanType, 31, isAliceInitiator, 0, + bobCommitPoint, *fundingTxIn, chanType, testAssetId, isAliceInitiator, 0, ) if err != nil { return nil, nil, nil, err @@ -342,7 +351,7 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( IsInitiator: isAliceInitiator, BtcCapacity: channelBtcCapacity, AssetCapacity: channelAssetCapacity, - AssetID: 31, + AssetID: testAssetId, RemoteCurrentRevocation: bobCommitPoint, RevocationProducer: alicePreimageProducer, RevocationStore: shachain.NewRevocationStore(), @@ -362,7 +371,7 @@ func CreateTestChannels(chanType channeldb.ChannelType) ( IsInitiator: !isAliceInitiator, BtcCapacity: channelBtcCapacity, AssetCapacity: 0, - AssetID: 31, + AssetID: testAssetId, RemoteCurrentRevocation: aliceCommitPoint, RevocationProducer: bobPreimageProducer, RevocationStore: shachain.NewRevocationStore(), diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index ff0b3f3d18..f093f8f7ed 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -1212,7 +1212,9 @@ func (l *LightningWallet) initOurContribution(reservation *ChannelReservation, ) reservation.partialState.RevocationProducer = producer - reservation.ourContribution.ChannelConstraints = l.Cfg.DefaultConstraints + defaultConstraints:=l.Cfg.DefaultConstraints + defaultConstraints.LoadCfg(reservation.partialState.AssetID) + reservation.ourContribution.ChannelConstraints = defaultConstraints return nil } diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go index 4c7aedb9d2..4a916b9fdd 100644 --- a/lnwire/accept_channel.go +++ b/lnwire/accept_channel.go @@ -5,7 +5,6 @@ import ( "io" "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/tlv" ) @@ -22,22 +21,26 @@ type AcceptChannel struct { // would like enforced on their version of the commitment transaction. // Any output below this value will be "trimmed" from the commitment // transaction, with the amount of the HTLC going to dust. - DustLimit btcutil.Amount + //DustLimit btcutil.Amount + DustLimit uint64 // MaxValueInFlight represents the maximum amount of coins that can be // pending within the channel at any given time. If the amount of funds // in limbo exceeds this amount, then the channel will be failed. - MaxValueInFlight MilliSatoshi + //MaxValueInFlight MilliSatoshi + MaxValueInFlight uint64 // ChannelReserve is the amount of BTC that the receiving party MUST // maintain a balance above at all times. This is a safety mechanism to // ensure that both sides always have skin in the game during the // channel's lifetime. - ChannelReserve btcutil.Amount + //ChannelReserve btcutil.Amount + ChannelReserve uint64 // HtlcMinimum is the smallest HTLC that the sender of this message // will accept. - HtlcMinimum MilliSatoshi + //HtlcMinimum MilliSatoshi + HtlcMinimum uint64 // MinAcceptDepth is the minimum depth that the initiator of the // channel should wait before considering the channel open. @@ -143,19 +146,19 @@ func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { return err } - if err := WriteSatoshi(w, a.DustLimit); err != nil { + if err := WriteUint64(w, a.DustLimit); err != nil { return err } - if err := WriteMilliSatoshi(w, a.MaxValueInFlight); err != nil { + if err := WriteUint64(w, a.MaxValueInFlight); err != nil { return err } - if err := WriteSatoshi(w, a.ChannelReserve); err != nil { + if err := WriteUint64(w, a.ChannelReserve); err != nil { return err } - if err := WriteMilliSatoshi(w, a.HtlcMinimum); err != nil { + if err := WriteUint64(w, a.HtlcMinimum); err != nil { return err } diff --git a/lnwire/msat.go b/lnwire/msat.go index d3789dfa31..b64241c549 100644 --- a/lnwire/msat.go +++ b/lnwire/msat.go @@ -2,8 +2,8 @@ package lnwire import ( "fmt" - "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" ) const ( @@ -49,3 +49,27 @@ func (m MilliSatoshi) String() string { } // TODO(roasbeef): extend with arithmetic operations? + + + +//RequiredRemoteMaxValue +func AmtToMstat(assetId uint32,amt uint64) uint64{ + if assetId==omnicore.BtcAssetId{ + return amt * 1000 + }else { + return amt + } +} + +func MstatCfgToI64(assetId uint32,mstat MilliSatoshi) uint64{ + if assetId==omnicore.BtcAssetId{ + return uint64(mstat) + }else{ + //truncate MilliSatoshi to 8 precision + //res:= uint64(mstat/1000) + // + //// get usdt value,btc/usdt ~ 30000 + //return res *30000 + return uint64(mstat*30000/1000) + } +} diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go index 211c328c46..ddb481a8af 100644 --- a/lnwire/open_channel.go +++ b/lnwire/open_channel.go @@ -59,22 +59,22 @@ type OpenChannel struct { // would like enforced on their version of the commitment transaction. // Any output below this value will be "trimmed" from the commitment // transaction, with the amount of the HTLC going to dust. - DustLimit btcutil.Amount + DustLimit uint64 // MaxValueInFlight represents the maximum amount of coins that can be // pending within the channel at any given time. If the amount of funds // in limbo exceeds this amount, then the channel will be failed. - MaxValueInFlight MilliSatoshi + MaxValueInFlight uint64 // ChannelReserve is the amount of BTC that the receiving party MUST // maintain a balance above at all times. This is a safety mechanism to // ensure that both sides always have skin in the game during the // channel's lifetime. - ChannelReserve btcutil.Amount + ChannelReserve uint64 // HtlcMinimum is the smallest HTLC that the sender of this message // will accept. - HtlcMinimum MilliSatoshi + HtlcMinimum uint64 // FeePerKiloWeight is the initial fee rate that the initiator suggests // for both commitment transaction. This value is expressed in sat per @@ -208,19 +208,20 @@ func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error { return err } - if err := WriteSatoshi(w, o.DustLimit); err != nil { + /*obd update wxf*/ + if err := WriteUint64(w, o.DustLimit); err != nil { return err } - if err := WriteMilliSatoshi(w, o.MaxValueInFlight); err != nil { + if err := WriteUint64(w, o.MaxValueInFlight); err != nil { return err } - if err := WriteSatoshi(w, o.ChannelReserve); err != nil { + if err := WriteUint64(w, o.ChannelReserve); err != nil { return err } - if err := WriteMilliSatoshi(w, o.HtlcMinimum); err != nil { + if err := WriteUint64(w, o.HtlcMinimum); err != nil { return err } diff --git a/peer/brontide.go b/peer/brontide.go index 51d2dc325f..58f2fb9431 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -742,6 +742,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) ( "for channel %v, using default values", chanPoint) forwardingPolicy = &p.cfg.RoutingPolicy + forwardingPolicy.LoadCfg(dbChan.AssetID) } peerLog.Tracef("Using link policy of: %v", @@ -1606,7 +1607,7 @@ func messageSummary(msg lnwire.Message) string { return fmt.Sprintf("temp_chan_id=%x, chain=%v, csv=%v, amt=%v, "+ "push_amt=%v, reserve=%v, flags=%v", msg.PendingChannelID[:], msg.ChainHash, - msg.CsvDelay, msg.FundingAmount, msg.PushAmount, + msg.CsvDelay, msg.FundingBtcAmount, msg.PushBtcAmount, msg.ChannelReserve, msg.ChannelFlags) case *lnwire.AcceptChannel: @@ -2277,6 +2278,7 @@ out: // defaults to the cap on the total value of outstanding HTLCs. fwdMinHtlc := lnChan.FwdMinHtlc() defaultPolicy := p.cfg.RoutingPolicy + defaultPolicy.LoadCfg(newChan.AssetID) forwardingPolicy := &htlcswitch.ForwardingPolicy{ MinHTLCOut: fwdMinHtlc, MaxHTLC: newChan.LocalChanCfg.MaxPendingAmount, diff --git a/peer/test_utils.go b/peer/test_utils.go index 0c044091c9..ca82dc2d0f 100644 --- a/peer/test_utils.go +++ b/peer/test_utils.go @@ -4,6 +4,7 @@ import ( "bytes" crand "crypto/rand" "encoding/binary" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "io" "io/ioutil" "math/rand" @@ -89,10 +90,12 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, aliceCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ - DustLimit: aliceDustLimit, - MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), - ChanReserve: btcutil.Amount(rand.Int63()), - MinHTLC: lnwire.MilliSatoshi(rand.Int63()), + Cfg: channeldb.ChannelConstraintsCfg{ + DustLimit: aliceDustLimit, + MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), + ChanReserve: btcutil.Amount(rand.Int63()), + MinHTLC: lnwire.MilliSatoshi(rand.Int63()), + }, MaxAcceptedHtlcs: uint16(rand.Int31()), CsvDelay: uint16(csvTimeoutAlice), }, @@ -112,12 +115,15 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, PubKey: aliceKeyPub, }, } + aliceCfg.LoadCfg(omnicore.BtcAssetId) bobCfg := channeldb.ChannelConfig{ ChannelConstraints: channeldb.ChannelConstraints{ - DustLimit: bobDustLimit, - MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), - ChanReserve: btcutil.Amount(rand.Int63()), - MinHTLC: lnwire.MilliSatoshi(rand.Int63()), + Cfg: channeldb.ChannelConstraintsCfg{ + DustLimit: bobDustLimit, + MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()), + ChanReserve: btcutil.Amount(rand.Int63()), + MinHTLC: lnwire.MilliSatoshi(rand.Int63()), + }, MaxAcceptedHtlcs: uint16(rand.Int31()), CsvDelay: uint16(csvTimeoutBob), }, @@ -137,6 +143,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, PubKey: bobKeyPub, }, } + bobCfg.LoadCfg(omnicore.BtcAssetId) bobRoot, err := chainhash.NewHash(bobKeyPriv.Serialize()) if err != nil { @@ -161,8 +168,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:]) aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns( - channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, - bobCommitPoint, *fundingTxIn, channeldb.SingleFunderTweaklessBit, + channelBal, channelBal,0,0, &aliceCfg, &bobCfg, aliceCommitPoint, + bobCommitPoint, *fundingTxIn, channeldb.SingleFunderTweaklessBit, omnicore.BtcAssetId, isAliceInitiator, 0, ) if err != nil { @@ -198,8 +205,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, // TODO(roasbeef): need to factor in commit fee? aliceCommit := channeldb.ChannelCommitment{ CommitHeight: 0, - LocalBalance: lnwire.NewMSatFromSatoshis(channelBal), - RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal), + LocalBtcBalance: lnwire.NewMSatFromSatoshis(channelBal), + RemoteBtcBalance: lnwire.NewMSatFromSatoshis(channelBal), FeePerKw: btcutil.Amount(feePerKw), CommitFee: feePerKw.FeeForWeight(input.CommitWeight), CommitTx: aliceCommitTx, @@ -207,8 +214,8 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, } bobCommit := channeldb.ChannelCommitment{ CommitHeight: 0, - LocalBalance: lnwire.NewMSatFromSatoshis(channelBal), - RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal), + LocalBtcBalance: lnwire.NewMSatFromSatoshis(channelBal), + RemoteBtcBalance: lnwire.NewMSatFromSatoshis(channelBal), FeePerKw: btcutil.Amount(feePerKw), CommitFee: feePerKw.FeeForWeight(input.CommitWeight), CommitTx: bobCommitTx, @@ -232,7 +239,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, ShortChannelID: shortChanID, ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: isAliceInitiator, - Capacity: channelCapacity, + BtcCapacity: channelCapacity, RemoteCurrentRevocation: bobCommitPoint, RevocationProducer: alicePreimageProducer, RevocationStore: shachain.NewRevocationStore(), @@ -249,7 +256,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, FundingOutpoint: *prevOut, ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: !isAliceInitiator, - Capacity: channelCapacity, + BtcCapacity: channelCapacity, RemoteCurrentRevocation: aliceCommitPoint, RevocationProducer: bobPreimageProducer, RevocationStore: shachain.NewRevocationStore(), diff --git a/routing/pathfind.go b/routing/pathfind.go index 405da07b96..af0450d536 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -4,6 +4,7 @@ import ( "container/heap" "errors" "fmt" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "math" "time" @@ -396,7 +397,7 @@ func getOutgoingBalance(assetId uint32,node route.Vertex, outgoingChans map[uint if !ok { /*obd update wxf*/ //bandwidth = lnwire.NewMSatFromSatoshis(channel.Capacity) - if channel.AssetId==1{ + if channel.AssetId==omnicore.BtcAssetId{ bandwidth = channel.Capacity*1000 }else{ bandwidth = channel.Capacity @@ -432,6 +433,9 @@ func getOutgoingBalance(assetId uint32,node route.Vertex, outgoingChans map[uint // source. This is to properly accumulate fees that need to be paid along the // path and accurately check the amount to forward at every node against the // available bandwidth. +//func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, +// source, target route.Vertex, amt lnwire.MilliSatoshi, +// finalHtlcExpiry int32) ([]*channeldb.CachedEdgePolicy, error) { func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, source, target route.Vertex, assetId uint32, amt uint64, finalHtlcExpiry int32) ([]*channeldb.CachedEdgePolicy, error) { @@ -912,6 +916,7 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, if !ok { // If the node doesn't have a next hop it means we // didn't find a path. + println("max %v < amt %v", "currentNode", amt ) return nil, errNoPathFound } diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index d9f592db72..0dcbaa6ef5 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "io/ioutil" "math" "math/big" @@ -355,13 +356,17 @@ func parseTestGraph(assetId uint32,useCache bool, path string) (*testGraphInstan Index: 0, } + cap:=edge.Capacity*30000 + if assetId==omnicore.BtcAssetId{ + cap=edge.Capacity + } // We first insert the existence of the edge between the two // nodes. edgeInfo := channeldb.ChannelEdgeInfo{ ChannelID: edge.ChannelID, AuthProof: &testAuthProof, ChannelPoint: fundingPoint, - Capacity: edge.Capacity, + Capacity: cap, AssetId: edge.AssetID, } @@ -372,9 +377,9 @@ func parseTestGraph(assetId uint32,useCache bool, path string) (*testGraphInstan shortID := lnwire.NewShortChanIDFromInt(edge.ChannelID) - bw:=edgeInfo.Capacity * 1000 - if edge.AssetID>1{ - bw=edgeInfo.Capacity + bw:=uint64(edgeInfo.Capacity * 1000) + if assetId==omnicore.BtcAssetId{ + bw=uint64(edgeInfo.Capacity*30) } links[shortID] = &mockLink{ assetId:edge.AssetID, @@ -401,10 +406,10 @@ func parseTestGraph(assetId uint32,useCache bool, path string) (*testGraphInstan AssetId: edge.AssetID, LastUpdate: testTime, TimeLockDelta: edge.Expiry, - MinHTLC: edge.MinHTLC, - MaxHTLC: edge.MaxHTLC, - FeeBaseMSat: edge.FeeBaseMsat, - FeeProportionalMillionths: edge.FeeRate, + MinHTLC: lnwire.MstatCfgToI64(assetId,lnwire.MilliSatoshi(edge.MinHTLC)), + MaxHTLC: lnwire.MstatCfgToI64(assetId,lnwire.MilliSatoshi(edge.MaxHTLC)), + FeeBaseMSat: lnwire.MstatCfgToI64(assetId,lnwire.MilliSatoshi(edge.FeeBaseMsat)), + FeeProportionalMillionths: uint64(lnwire.MilliSatoshi(edge.FeeRate)), Node: &channeldb.LightningNode{ Alias: aliasForNode(targetNode), PubKeyBytes: targetNode, @@ -663,7 +668,7 @@ func createTestGraphFromChannels(assetId uint32,useCache bool, testChannels []*t capacity := testChannel.Capacity - if assetId==1{ + if assetId==omnicore.BtcAssetId{ capacity = testChannel.Capacity*1000 } shortID := lnwire.NewShortChanIDFromInt(channelID) @@ -937,7 +942,7 @@ func runFindLowestFeePath(t *testing.T, assetId uint32,useCache bool) { //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt = uint64(100*1000) } target := ctx.keyFromAlias("target") @@ -1075,7 +1080,7 @@ func testBasicGraphPathFindingCase(t *testing.T, assetId uint32, graphInstance * //paymentAmt := lnwire.NewMSatFromSatoshis(test.paymentAmt) paymentAmt := uint64(test.paymentAmt) - if assetId==1 { + if assetId==omnicore.BtcAssetId { paymentAmt = uint64(test.paymentAmt * 1000) } target := graphInstance.aliasMap[test.target] @@ -1231,7 +1236,7 @@ func runPathFindingWithAdditionalEdges(t *testing.T, assetId uint32, useCache bo //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt = uint64(100*1000) } @@ -2545,7 +2550,7 @@ func runRestrictOutgoingChannel(t *testing.T,assetId uint32, useCache bool) { //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt = uint64(100*1000) } @@ -2610,7 +2615,7 @@ func runRestrictLastHop(t *testing.T,assetId uint32, useCache bool) { //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt = uint64(100*1000) } target := ctx.keyFromAlias("target") @@ -2685,7 +2690,7 @@ func testCltvLimit(t *testing.T,assetId uint32, useCache bool, limit uint32, //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64( 100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt = uint64(1000 * 100) } target := ctx.keyFromAlias("target") @@ -2939,7 +2944,7 @@ func runEqualCostRouteSelection(t *testing.T,assetId uint32, useCache bool) { //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt= uint64(100*1000) } target := ctx.testGraphInstance.aliasMap["target"] @@ -3071,7 +3076,7 @@ func runRouteToSelf(t *testing.T,assetId uint32, useCache bool) { //paymentAmt := lnwire.NewMSatFromSatoshis(100) paymentAmt := uint64(100) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt=paymentAmt*1000 } target := ctx.source diff --git a/routing/payment_session.go b/routing/payment_session.go index 26be3deaaa..7b0c0e9aba 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -2,6 +2,7 @@ package routing import ( "fmt" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btclog" @@ -218,7 +219,7 @@ func newPaymentSession(p *LightningPayment, }, nil } func getAmtValue(msat lnwire.MilliSatoshi,assetId uint32) uint64{ - if assetId>1{ //asset + if assetId!=omnicore.BtcAssetId{ //asset return uint64(msat /1000) } //btc diff --git a/routing/router.go b/routing/router.go index 6a5466cf52..b8b323aa09 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1735,6 +1735,11 @@ type routingMsg struct { // FindRoute attempts to query the ChannelRouter for the optimum path to a // particular target destination to which it is able to send `amt` after // factoring in channel capacities and cumulative fees along the route. +//func (r *ChannelRouter) FindRoute(source, target route.Vertex, +// amt lnwire.MilliSatoshi, restrictions *RestrictParams, +// destCustomRecords record.CustomSet, +// routeHints map[route.Vertex][]*channeldb.CachedEdgePolicy, +// finalExpiry uint16) (*route.Route, error) { func (r *ChannelRouter) FindRoute(source, target route.Vertex, //amt lnwire.MilliSatoshi, restrictions *RestrictParams, assetId uint32, amt uint64, restrictions *RestrictParams, diff --git a/routing/router_test.go b/routing/router_test.go index b3a9097d89..66537b0c8c 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -3,6 +3,7 @@ package routing import ( "bytes" "fmt" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "image/color" "math" "math/rand" @@ -244,7 +245,7 @@ func signErrChanUpdate(t *testing.T, key *btcec.PrivateKey, // limit. func TestFindRoutesWithFeeLimit(t *testing.T) { t.Parallel() - assetId:=uint32(1) + //assetId:=uint32(1) const startingBlockHeight = 101 ctx, cleanUp := createTestCtxFromFile( t, assetId, startingBlockHeight, basicGraphFilePath, @@ -261,12 +262,11 @@ func TestFindRoutesWithFeeLimit(t *testing.T) { target := ctx.aliases["sophon"] //paymentAmt := lnwire.NewMSatFromSatoshis(100) - - paymentAmt := uint64( 100) - feeLimit:=uint64( 10) - if assetId>0{ - paymentAmt=1000*paymentAmt - feeLimit=1000*feeLimit + paymentAmt := uint64(100)*30000 + feeLimit:=uint64( 10)*30000 + if assetId==omnicore.BtcAssetId{ + paymentAmt=1000*uint64( 100) + feeLimit=1000*uint64( 10) } restrictions := &RestrictParams{ FeeLimit: feeLimit, @@ -382,7 +382,7 @@ func TestChannelUpdateValidation(t *testing.T) { feeRate := uint64(400) maxHtlc:=chanCapSat - if assetId==1{ + if assetId==omnicore.BtcAssetId{ maxHtlc=maxHtlc*1000 } testChannels := []*testChannel{ @@ -439,7 +439,7 @@ func TestChannelUpdateValidation(t *testing.T) { } ramt:=uint64(10) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ ramt=10*1000 } rt, err := route.NewRouteFromHops( @@ -648,7 +648,7 @@ func TestSendPaymentErrorFeeInsufficientPrivateEdge(t *testing.T) { expiryDelta = uint16(32) sgNode = ctx.aliases["songoku"] ) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ amt*=1000 } sgNodeID, err := btcec.ParsePubKey(sgNode[:], btcec.S256()) @@ -786,7 +786,7 @@ func TestSendPaymentPrivateEdgeUpdateFeeExceedsLimit(t *testing.T) { sgNode = ctx.aliases["songoku"] feeLimit = uint64(500000) ) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ amt*=1000 } sgNodeID, err := btcec.ParsePubKey(sgNode[:], btcec.S256()) @@ -1026,7 +1026,7 @@ func TestSendPaymentErrorPathPruning(t *testing.T) { var payHash lntypes.Hash //paymentAmt := lnwire.NewMSatFromSatoshis(1000) paymentAmt := uint64(1) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt=1000 } payment := LightningPayment{ @@ -2770,7 +2770,7 @@ func TestUnknownErrorSource(t *testing.T) { // alternative a->d->c. chanCapSat := uint64(100000) mHtlc:=chanCapSat - if assetId==1{ + if assetId==omnicore.BtcAssetId{ mHtlc=mHtlc*1000 } testChannels := []*testChannel{ @@ -2815,7 +2815,7 @@ func TestUnknownErrorSource(t *testing.T) { defer cleanUp() pAmt:=uint64( 1000) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ pAmt=pAmt*1000 } // Create a payment to node c. @@ -2920,9 +2920,9 @@ func assertChannelsPruned(t *testing.T, graph *channeldb.ChannelGraph, } } } -var assetId =uint32(1) +var assetId =uint32(31) func getPayValue(msat lnwire.MilliSatoshi) uint64{ - if assetId>1{ //asset + if assetId!=omnicore.BtcAssetId{ //asset return uint64(msat /1000) } //btc @@ -2936,7 +2936,7 @@ func TestSendToRouteStructuredError(t *testing.T) { // Setup a three node network. chanCapSat := uint64(100000) mHtlc:=chanCapSat - if assetId==1{ + if assetId==omnicore.BtcAssetId{ mHtlc=mHtlc*1000 } testChannels := []*testChannel{ @@ -2975,7 +2975,7 @@ func TestSendToRouteStructuredError(t *testing.T) { // in a call to SendToRoute. SendToRoute also applies channel updates, // but it saves us from including RequestRoute in the test scope too. var payAmt = uint64(10000) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ payAmt=payAmt*1000 } hop1 := ctx.aliases["b"] @@ -3198,7 +3198,7 @@ func TestSendToRouteMaxHops(t *testing.T) { // Setup a two node network. chanCapSat := uint64(100000) mHtlc:=chanCapSat - if assetId==1 { + if assetId==omnicore.BtcAssetId { mHtlc=mHtlc*1000 } testChannels := []*testChannel{ @@ -3225,7 +3225,7 @@ func TestSendToRouteMaxHops(t *testing.T) { // Create a 30 hop route that exceeds the maximum hop limit. var payAmt = uint64(10000) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ payAmt=payAmt*1000 } hopA := ctx.aliases["a"] @@ -3323,7 +3323,7 @@ func TestBuildRoute(t *testing.T) { Features: paymentAddrFeatures, }, 4), } - if assetId==1{ + if assetId==omnicore.BtcAssetId{ for _, channel := range testChannels { channel.Node1.MaxHTLC*=1000 channel.Node1.MinHTLC*=1000 @@ -3556,7 +3556,7 @@ func createDummyTestGraph(t *testing.T) *testGraphInstance { // route. chanCapSat := uint64(100000) maxHtlc:=chanCapSat - if assetId==1{ + if assetId==omnicore.BtcAssetId{ maxHtlc*=1000 } testChannels := []*testChannel{ @@ -4229,7 +4229,7 @@ func TestSendMPPaymentFailedWithShardsInFlight(t *testing.T) { // resumePayment. //paymentAmt := lnwire.MilliSatoshi(10000) paymentAmt := uint64(10) - if assetId==1{ + if assetId==omnicore.BtcAssetId{ paymentAmt*=1000 } req := createDummyLightningPayment( diff --git a/routing/unified_policies.go b/routing/unified_policies.go index 156b0d5615..e6c95a803b 100644 --- a/routing/unified_policies.go +++ b/routing/unified_policies.go @@ -1,7 +1,9 @@ package routing import ( + "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -103,11 +105,16 @@ type unifiedPolicyEdge struct { //func (u *unifiedPolicyEdge) amtInRange(amt lnwire.MilliSatoshi) bool { /*obd update wxf*/ func (u *unifiedPolicyEdge) amtInRange(amt uint64) bool { + + capAmout:=u.capacity + if u.policy.AssetId==omnicore.BtcAssetId{ + capAmout=uint64(lnwire.NewMSatFromSatoshis(btcutil.Amount( u.capacity))) + } // If the capacity is available (non-light clients), skip channels that // are too small. if u.capacity > 0 && //amt > lnwire.NewMSatFromSatoshis(u.capacity) { - amt > u.capacity*1000 { + amt > capAmout { return false } diff --git a/server.go b/server.go index 82aadd1fed..a0f021c1f0 100644 --- a/server.go +++ b/server.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "github.com/lightningnetwork/lnd/lnwallet/omnicore" "image/color" "math/big" prand "math/rand" @@ -1298,7 +1299,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, return s.htlcSwitch.UpdateShortChanID(cid) }, RequiredRemoteChanReserve: func(chanAmt, - dustLimit btcutil.Amount) btcutil.Amount { + dustLimit uint64) uint64 { // By default, we'll require the remote peer to maintain // at least 1% of the total channel capacity at all @@ -1312,12 +1313,16 @@ func newServer(cfg *Config, listenAddrs []net.Addr, return reserve }, - RequiredRemoteMaxValue: func(chanAmt btcutil.Amount) lnwire.MilliSatoshi { + /*obd update wxf*/ + RequiredRemoteMaxValue: func(assetId uint32, chanAmt uint64) uint64 { // By default, we'll allow the remote peer to fully // utilize the full bandwidth of the channel, minus our // required reserve. - reserve := lnwire.NewMSatFromSatoshis(chanAmt / 100) - return lnwire.NewMSatFromSatoshis(chanAmt) - reserve + if assetId==omnicore.BtcAssetId { + reserve := lnwire.NewMSatFromSatoshis(btcutil.Amount(chanAmt) / 100) + return uint64(lnwire.NewMSatFromSatoshis(btcutil.Amount(chanAmt)) - reserve) + } + return chanAmt-chanAmt / 100 }, RequiredRemoteMaxHTLCs: func(chanAmt btcutil.Amount) uint16 { if cfg.DefaultRemoteMaxHtlcs > 0 {