diff --git a/loopdb/swapstate.go b/loopdb/swapstate.go index 87c21f3..c2cddb2 100644 --- a/loopdb/swapstate.go +++ b/loopdb/swapstate.go @@ -60,6 +60,10 @@ const ( // StateInvoiceSettled means that the swap invoice has been paid by the // server. StateInvoiceSettled SwapState = 9 + + // StateFailIncorrectHtlcAmt indicates that the amount of an externally + // published loop in htlc didn't match the swap amount. + StateFailIncorrectHtlcAmt SwapState = 10 ) // SwapStateType defines the types of swap states that exist. Every swap state @@ -127,6 +131,9 @@ func (s SwapState) String() string { case StateInvoiceSettled: return "InvoiceSettled" + case StateFailIncorrectHtlcAmt: + return "IncorrectHtlcAmt" + default: return "Unknown" } diff --git a/loopin.go b/loopin.go index bc0fcc3..40495e2 100644 --- a/loopin.go +++ b/loopin.go @@ -363,6 +363,13 @@ func (s *loopInSwap) executeSwap(globalCtx context.Context) error { return err } + // Verify that the confirmed (external) htlc value matches the swap + // amount. Otherwise fail the swap immediately. + if htlcValue != s.LoopInContract.AmountRequested { + s.setState(loopdb.StateFailIncorrectHtlcAmt) + return s.persistAndAnnounceState(globalCtx) + } + // TODO: Add miner fee of htlc tx to swap cost balance. // The server is expected to see the htlc on-chain and knowing that it diff --git a/loopin_test.go b/loopin_test.go index 9765d76..51d52cf 100644 --- a/loopin_test.go +++ b/loopin_test.go @@ -209,6 +209,20 @@ func testLoopInTimeout(t *testing.T, Tx: &htlcTx, } + // Assert that the swap is failed in case of an invalid amount. + invalidAmt := externalValue != 0 && externalValue != int64(req.Amount) + if invalidAmt { + ctx.assertState(loopdb.StateFailIncorrectHtlcAmt) + ctx.store.assertLoopInState(loopdb.StateFailIncorrectHtlcAmt) + + err = <-errChan + if err != nil { + t.Fatal(err) + } + + return + } + // Client starts listening for spend of htlc. <-ctx.lnd.RegisterSpendChannel @@ -380,6 +394,7 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool) { htlcTx.AddTxOut(&wire.TxOut{ PkScript: htlc.PkScript, + Value: int64(contract.AmountRequested), }) }