99 "testing"
1010 "time"
1111
12+ "github.com/btcsuite/btcd/btcutil"
13+ "github.com/btcsuite/btcd/wire"
1214 "github.com/lightninglabs/taproot-assets/internal/test"
1315 "github.com/lightninglabs/taproot-assets/proof"
1416 "github.com/lightninglabs/taproot-assets/tapfreighter"
@@ -18,7 +20,9 @@ import (
1820 "github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc"
1921 unirpc "github.com/lightninglabs/taproot-assets/taprpc/universerpc"
2022 "github.com/lightninglabs/taproot-assets/tapsend"
23+ "github.com/lightningnetwork/lnd/lnrpc"
2124 "github.com/lightningnetwork/lnd/lntest/wait"
25+ "github.com/lightningnetwork/lnd/lnwallet/chainfee"
2226 "github.com/stretchr/testify/require"
2327)
2428
@@ -140,6 +144,144 @@ func testBasicSendUnidirectional(t *harnessTest) {
140144 wg .Wait ()
141145}
142146
147+ // testMinRelayFeeBump tests that if the fee estimation is below the min relay
148+ // fee the feerate is bumped to the min relay fee for both the minting
149+ // transaction and a basic asset send.
150+ func testMinRelayFeeBump (t * harnessTest ) {
151+ var ctxb = context .Background ()
152+
153+ const numUnits = 10
154+
155+ // Subscribe to receive assent send events from primary tapd node.
156+ events := SubscribeSendEvents (t .t , t .tapd )
157+
158+ // We will mint assets using the first output and then use the second
159+ // output for the transfer. This ensures a valid fee calculation.
160+ initialUTXOs := []* UTXORequest {
161+ {
162+ Type : lnrpc .AddressType_NESTED_PUBKEY_HASH ,
163+ Amount : 1_000_000 ,
164+ },
165+ {
166+ Type : lnrpc .AddressType_NESTED_PUBKEY_HASH ,
167+ Amount : 999_990 ,
168+ },
169+ }
170+
171+ // Set the initial state of the wallet of the first node. The wallet
172+ // state will reset at the end of this test.
173+ SetNodeUTXOs (t , t .lndHarness .Alice , btcutil .Amount (1 ), initialUTXOs )
174+ defer ResetNodeWallet (t , t .lndHarness .Alice )
175+
176+ // Set the min relay fee to a higher value than the fee rate that will
177+ // be returned by the fee estimation.
178+ lowFeeRate := chainfee .SatPerVByte (1 ).FeePerKWeight ()
179+ highMinRelayFeeRate := chainfee .SatPerVByte (2 ).FeePerKVByte ()
180+ defaultMinRelayFeeRate := chainfee .SatPerVByte (1 ).FeePerKVByte ()
181+ defaultFeeRate := chainfee .SatPerKWeight (3125 )
182+ t .lndHarness .SetFeeEstimateWithConf (lowFeeRate , 6 )
183+ t .lndHarness .SetMinRelayFeerate (highMinRelayFeeRate )
184+
185+ // Reset all fee rates to their default value at the end of this test.
186+ defer t .lndHarness .SetMinRelayFeerate (defaultMinRelayFeeRate )
187+ defer t .lndHarness .SetFeeEstimateWithConf (defaultFeeRate , 6 )
188+
189+ // First, we'll make a normal assets with enough units to allow us to
190+ // send it around a few times.
191+ MintAssetsConfirmBatch (
192+ t .t , t .lndHarness .Miner ().Client , t .tapd ,
193+ []* mintrpc.MintAssetRequest {issuableAssets [0 ]},
194+ WithFeeRate (uint32 (lowFeeRate )),
195+ WithError ("manual fee rate below floor" ),
196+ )
197+
198+ MintAssetsConfirmBatch (
199+ t .t , t .lndHarness .Miner ().Client , t .tapd ,
200+ []* mintrpc.MintAssetRequest {issuableAssets [0 ]},
201+ WithFeeRate (uint32 (lowFeeRate )+ 10 ),
202+ WithError ("feerate does not meet minrelayfee" ),
203+ )
204+
205+ rpcAssets := MintAssetsConfirmBatch (
206+ t .t , t .lndHarness .Miner ().Client , t .tapd ,
207+ []* mintrpc.MintAssetRequest {issuableAssets [0 ]},
208+ )
209+
210+ genInfo := rpcAssets [0 ].AssetGenesis
211+
212+ // Check the final fee rate of the mint TX.
213+ rpcMintOutpoint := rpcAssets [0 ].ChainAnchor .AnchorOutpoint
214+ mintOutpoint , err := wire .NewOutPointFromString (rpcMintOutpoint )
215+ require .NoError (t .t , err )
216+
217+ // We check whether the minting TX is bumped to the min relay fee.
218+ AssertFeeRate (
219+ t .t , t .lndHarness .Miner ().Client , initialUTXOs [0 ].Amount ,
220+ & mintOutpoint .Hash , highMinRelayFeeRate .FeePerKWeight (),
221+ )
222+
223+ // Now that we have the asset created, we'll make a new node that'll
224+ // serve as the node which'll receive the assets. The existing tapd
225+ // node will be used to synchronize universe state.
226+ secondTapd := setupTapdHarness (
227+ t .t , t , t .lndHarness .Bob , t .universeServer ,
228+ )
229+ defer func () {
230+ require .NoError (t .t , secondTapd .stop (! * noDelete ))
231+ }()
232+
233+ // Next, we'll attempt to complete two transfers with distinct
234+ // addresses from our main node to Bob.
235+ currentUnits := issuableAssets [0 ].Asset .Amount
236+
237+ // Issue a single address which will be reused for each send.
238+ bobAddr , err := secondTapd .NewAddr (ctxb , & taprpc.NewAddrRequest {
239+ AssetId : genInfo .AssetId ,
240+ Amt : numUnits ,
241+ AssetVersion : rpcAssets [0 ].Version ,
242+ })
243+ require .NoError (t .t , err )
244+
245+ // Deduct what we sent from the expected current number of
246+ // units.
247+ currentUnits -= numUnits
248+
249+ AssertAddrCreated (t .t , secondTapd , rpcAssets [0 ], bobAddr )
250+
251+ sendAsset (
252+ t , t .tapd , withReceiverAddresses (bobAddr ),
253+ withFeeRate (uint32 (lowFeeRate )),
254+ withError ("manual fee rate below floor" ),
255+ )
256+
257+ sendAsset (
258+ t , t .tapd , withReceiverAddresses (bobAddr ),
259+ withFeeRate (uint32 (lowFeeRate )+ 10 ),
260+ withError ("feerate does not meet minrelayfee" ),
261+ )
262+
263+ sendResp , sendEvents := sendAssetsToAddr (t , t .tapd , bobAddr )
264+
265+ ConfirmAndAssertOutboundTransfer (
266+ t .t , t .lndHarness .Miner ().Client , t .tapd , sendResp ,
267+ genInfo .AssetId ,
268+ []uint64 {currentUnits , numUnits }, 0 , 1 ,
269+ )
270+
271+ sendInputAmt := initialUTXOs [1 ].Amount + 1000
272+ AssertTransferFeeRate (
273+ t .t , t .lndHarness .Miner ().Client , sendResp , sendInputAmt ,
274+ highMinRelayFeeRate .FeePerKWeight (),
275+ )
276+
277+ AssertNonInteractiveRecvComplete (t .t , secondTapd , 1 )
278+ AssertSendEventsComplete (t .t , bobAddr .ScriptKey , sendEvents )
279+
280+ // Close event stream.
281+ err = events .CloseSend ()
282+ require .NoError (t .t , err )
283+ }
284+
143285// testRestartReceiver tests that the receiver node's asset balance after a
144286// single asset transfer does not change if the receiver node restarts.
145287// Before the addition of this test, after restarting the receiver node
0 commit comments