Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: move less-than-1-sat legacy integration test to bats #3253

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions test/bats/helpers/ln.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ source $(dirname "$BASH_SOURCE")/_common.bash
LND_FUNDING_TOKEN_NAME="lnd_funding"
LND_FUNDING_PHONE="+16505554351"

LNDS_REST_LOG=".e2e-lnds-rest.log"

mempool_not_empty() {
local txid="$(bitcoin_cli getrawmempool | jq -r ".[0]")"
[[ "$txid" != "null" ]] || exit 1
Expand Down Expand Up @@ -179,6 +181,26 @@ lnd_outside_cli() {
$@
}

lnd_outside_rest() {
local route=$1
local endpoint="https://localhost:8080/$route"

local data=$2

local macaroon_hex=$(
docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \
xxd -p -c 10000 /root/.lnd/admin.macaroon
)

docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \
curl -s \
--cacert /root/.lnd/tls.cert \
-H "Grpc-Metadata-macaroon: $macaroon_hex" \
${data:+ -X POST -d $data} \
"$endpoint" \
> "$LNDS_REST_LOG"
}

lnd_outside_2_cli() {
docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-2-1" \
lncli \
Expand Down
47 changes: 46 additions & 1 deletion test/bats/ln-receive.bats
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ usd_amount=50
}

@test "ln-receive: settle via ln for BTC wallet, amountless invoice" {
# Generate invoice
token_name="$ALICE_TOKEN_NAME"
btc_wallet_name="$token_name.btc_wallet_id"

# Generate invoice
variables=$(
jq -n \
--arg wallet_id "$(read_value $btc_wallet_name)" \
Expand All @@ -149,6 +149,51 @@ usd_amount=50
check_for_ln_update "$payment_hash" || exit 1
}

@test "ln-receive: handle less-than-1-sat ln payment for BTC wallet" {
token_name="$ALICE_TOKEN_NAME"
btc_wallet_name="$token_name.btc_wallet_id"

# Generate amountless invoice
invoice_variables=$(
jq -n \
--arg wallet_id "$(read_value $btc_wallet_name)" \
'{input: {walletId: $wallet_id}}'
)
exec_graphql "$token_name" 'ln-no-amount-invoice-create' "$invoice_variables"
invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')"

payment_request="$(echo $invoice | jq -r '.paymentRequest')"
[[ "${payment_request}" != "null" ]] || exit 1
payment_hash="$(echo $invoice | jq -r '.paymentHash')"
[[ "${payment_hash}" != "null" ]] || exit 1

# Check that invoice is retrievable from lnd1
invoice_from_lnd=$(lnd_cli lookupinvoice "$payment_hash")
[[ -n $invoice_from_lnd ]] || exit 1

# Receive less-than-1-sat payment
pay_variables=$(
jq -n \
--arg payment_request "$payment_request" \
--arg amt_msat "995" \
--arg timeout_seconds "5" \
'{payment_request: $payment_request, amt_msat: $amt_msat, timeout_seconds: $timeout_seconds}'\
| tr -d '[:space:]')
lnd_outside_rest "v2/router/send" "$pay_variables"

# Check that payment fails
response=$(tail -n 1 "$LNDS_REST_LOG")
[[ -n $response ]] || exit 1
pay_status=$(echo $response | jq -r '.result.status')
[[ "$pay_status" == "FAILED" ]] || exit 1
failure_reason=$(echo $response | jq -r '.result.failure_reason')
[[ "$failure_reason" == "FAILURE_REASON_INCORRECT_PAYMENT_DETAILS" ]] || exit 1

# Check that invoice is removed from lnd1
invoice_from_lnd=$(lnd_cli lookupinvoice "$payment_hash") || true
[[ -z $invoice_from_lnd ]] || exit 1
}

@test "ln-receive: settle via ln for USD wallet, amountless invoice" {
# Generate invoice
token_name="$ALICE_TOKEN_NAME"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
getDefaultWalletIdByPhone,
getError,
getHash,
getInvoice,
getPubKey,
getTransactionsForWalletId,
getUsdWalletIdByPhone,
Expand Down Expand Up @@ -281,57 +280,6 @@ describe("UserWallet - Lightning", () => {
])
})

it("receives 'less than 1 sat amount' invoice", async () => {
const mtokens = "995"
const lnInvoice = await Wallets.addInvoiceNoAmountForSelf({
walletId: walletIdB as WalletId,
})
if (lnInvoice instanceof Error) throw lnInvoice
const { paymentRequest: invoice, paymentHash: hash } = lnInvoice

safePayNoExpect({ lnd: lndOutside1, request: invoice, mtokens })
// TODO: we could use an event instead of a sleep
await sleep(500)

expect(
await Wallets.updatePendingInvoiceByPaymentHash({
paymentHash: hash,
logger: baseLogger,
}),
).not.toBeInstanceOf(Error)
// should be idempotent (not return error when called again)
expect(
await Wallets.updatePendingInvoiceByPaymentHash({
paymentHash: hash,
logger: baseLogger,
}),
).not.toBeInstanceOf(Error)

// Check that no new txns are added
const ledgerTxs = await LedgerService().getTransactionsByHash(hash)
if (ledgerTxs instanceof Error) throw ledgerTxs
expect(ledgerTxs).toHaveLength(0)

// Check that wallet invoice is deleted (was declined)
const walletInvoice = await WalletInvoicesRepository().findByPaymentHash(hash)
expect(walletInvoice).toBeInstanceOf(CouldNotFindWalletInvoiceError)

// Check that invoice is deleted in lnd
let getInvoiceErr
try {
await getInvoice({ lnd: lnd1, id: hash })
} catch (err) {
getInvoiceErr = err
}
expect(parseLndErrorDetails(getInvoiceErr)).toMatch(
KnownLndErrorDetails.InvoiceNotFound,
)

// Check that wallet balance is unchanged
const finalBalance = await getBalanceHelper(walletIdB)
expect(finalBalance).toBe(initBalanceB)
})

it("receives spam invoice", async () => {
// amount below MEMO_SPAM threshold
const sats = 100
Expand Down