From cab09a4ec34e4c2f7c429e236ec418702b0a022c Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Fri, 3 Nov 2023 09:34:40 -0500 Subject: [PATCH 1/5] chore(core): improve lightning resilience --- core/api/src/services/lnd/index.ts | 93 ++++++++++++++++++---- core/api/src/services/lnd/index.types.d.ts | 14 ++++ 2 files changed, 93 insertions(+), 14 deletions(-) diff --git a/core/api/src/services/lnd/index.ts b/core/api/src/services/lnd/index.ts index 2471494906..957a0b5d56 100644 --- a/core/api/src/services/lnd/index.ts +++ b/core/api/src/services/lnd/index.ts @@ -29,11 +29,8 @@ import { settleHodlInvoice, } from "lightning" import lnService from "ln-service" - import sumBy from "lodash.sumby" -import { KnownLndErrorDetails } from "./errors" - import { getActiveLnd, getActiveOnchainLnd, @@ -42,9 +39,12 @@ import { parseLndErrorDetails, } from "./config" +import { checkAllLndHealth } from "./health" + +import { KnownLndErrorDetails } from "./errors" + import { NETWORK, SECS_PER_5_MINS } from "@/config" -import { toMilliSatsFromString, toSats } from "@/domain/bitcoin" import { BadPaymentDataError, CorruptLndDbError, @@ -76,9 +76,10 @@ import { UnknownRouteNotFoundError, decodeInvoice, } from "@/domain/bitcoin/lightning" -import { IncomingOnChainTransaction } from "@/domain/bitcoin/onchain" import { CacheKeys } from "@/domain/cache" import { LnFees } from "@/domain/payments" +import { toMilliSatsFromString, toSats } from "@/domain/bitcoin" +import { IncomingOnChainTransaction } from "@/domain/bitcoin/onchain" import { WalletCurrency, paymentAmountFromNumber } from "@/domain/shared" import { LocalCacheService } from "@/services/cache" @@ -106,6 +107,9 @@ export const LndService = (): ILightningService | LightningServiceError => { const listActivePubkeys = (): Pubkey[] => getLnds({ active: true, type: "offchain" }).map((lndAuth) => lndAuth.pubkey as Pubkey) + const listActiveLnd = (): AuthenticatedLnd[] => + getLnds({ active: true, type: "offchain" }).map((lndAuth) => lndAuth.lnd) + const listAllPubkeys = (): Pubkey[] => getLnds({ type: "offchain" }).map((lndAuth) => lndAuth.pubkey as Pubkey) @@ -478,15 +482,18 @@ export const LndService = (): ILightningService | LightningServiceError => { } } - const registerInvoice = async ({ + const registerLndInvoice = async ({ + lnd, paymentHash, sats, description, descriptionHash, expiresAt, - }: RegisterInvoiceArgs): Promise => { + }: RegisterInvoiceArgs & { lnd: AuthenticatedLnd }): Promise< + RegisteredInvoice | LightningServiceError + > => { const input = { - lnd: defaultLnd, + lnd, id: paymentHash, description, description_hash: descriptionHash, @@ -511,6 +518,30 @@ export const LndService = (): ILightningService | LightningServiceError => { } } + const registerInvoice = async ({ + paymentHash, + sats, + description, + descriptionHash, + expiresAt, + }: RegisterInvoiceArgs): Promise => { + const lnds = listActiveLnd() + for (const lnd of lnds) { + const result = await registerLndInvoice({ + lnd, + paymentHash, + sats, + description, + descriptionHash, + expiresAt, + }) + if (isConnectionError(result)) continue + return result + } + + return new OffChainServiceUnavailableError("no active lightning node (for offchain)") + } + const lookupInvoice = async ({ pubkey, paymentHash, @@ -782,11 +813,13 @@ export const LndService = (): ILightningService | LightningServiceError => { } } - const payInvoiceViaPaymentDetails = async ({ + const payInvoiceViaPaymentDetailsWithLnd = async ({ + lnd, decodedInvoice, btcPaymentAmount, maxFeeAmount, }: { + lnd: AuthenticatedLnd decodedInvoice: LnInvoice btcPaymentAmount: BtcPaymentAmount maxFeeAmount: BtcPaymentAmount | undefined @@ -808,7 +841,7 @@ export const LndService = (): ILightningService | LightningServiceError => { } const paymentDetailsArgs: PayViaPaymentDetailsArgs = { - lnd: defaultLnd, + lnd, id: decodedInvoice.paymentHash, destination: decodedInvoice.destination, mtokens: milliSatsAmount.toString(), @@ -856,6 +889,30 @@ export const LndService = (): ILightningService | LightningServiceError => { } } + const payInvoiceViaPaymentDetails = async ({ + decodedInvoice, + btcPaymentAmount, + maxFeeAmount, + }: { + decodedInvoice: LnInvoice + btcPaymentAmount: BtcPaymentAmount + maxFeeAmount: BtcPaymentAmount | undefined + }): Promise => { + const lnds = listActiveLnd() + for (const lnd of lnds) { + const result = await payInvoiceViaPaymentDetailsWithLnd({ + lnd, + decodedInvoice, + btcPaymentAmount, + maxFeeAmount, + }) + if (isConnectionError(result)) continue + return result + } + + return new OffChainServiceUnavailableError("no active lightning node (for offchain)") + } + return wrapAsyncFunctionsToRunInSpan({ namespace: "services.lnd.offchain", fns: { @@ -982,16 +1039,17 @@ const lookupPaymentByPubkeyAndHash = async ({ } } -/* eslint @typescript-eslint/ban-ts-comment: "off" */ -// @ts-ignore-next-line no-implicit-any error -const translateLnPaymentLookup = (p): LnPaymentLookup => ({ +const isPaymentConfirmed = (p: PaymentResult): p is ConfirmedPaymentResult => + p.is_confirmed + +const translateLnPaymentLookup = (p: PaymentResult): LnPaymentLookup => ({ createdAt: new Date(p.created_at), status: p.is_confirmed ? PaymentStatus.Settled : PaymentStatus.Pending, paymentHash: p.id as PaymentHash, paymentRequest: p.request as EncodedPaymentRequest, milliSatsAmount: toMilliSatsFromString(p.mtokens), roundedUpAmount: toSats(p.safe_tokens), - confirmedDetails: p.is_confirmed + confirmedDetails: isPaymentConfirmed(p) ? { confirmedAt: new Date(p.confirmed_at), destination: p.destination as Pubkey, @@ -1139,8 +1197,10 @@ const handleCommonLightningServiceErrors = (err: Error | unknown) => { switch (true) { case match(KnownLndErrorDetails.ConnectionDropped): case match(KnownLndErrorDetails.NoConnectionEstablished): + checkAllLndHealth() return new OffChainServiceUnavailableError() case match(KnownLndErrorDetails.ConnectionRefused): + checkAllLndHealth() return new OffChainServiceBusyError() default: return new UnknownLightningServiceError(msgForUnknown(err as LnError)) @@ -1153,6 +1213,7 @@ const handleCommonRouteNotFoundErrors = (err: Error | unknown) => { switch (true) { case match(KnownLndErrorDetails.ConnectionDropped): case match(KnownLndErrorDetails.NoConnectionEstablished): + checkAllLndHealth() return new OffChainServiceUnavailableError() case match(KnownLndErrorDetails.MissingDependentFeature): @@ -1163,6 +1224,10 @@ const handleCommonRouteNotFoundErrors = (err: Error | unknown) => { } } +const isConnectionError = (result: unknown | LightningServiceError): boolean => + result instanceof OffChainServiceUnavailableError || + result instanceof OffChainServiceBusyError + const msgForUnknown = (err: LnError) => JSON.stringify({ parsedLndErrorDetails: parseLndErrorDetails(err), diff --git a/core/api/src/services/lnd/index.types.d.ts b/core/api/src/services/lnd/index.types.d.ts index d776bc561f..95519dcf89 100644 --- a/core/api/src/services/lnd/index.types.d.ts +++ b/core/api/src/services/lnd/index.types.d.ts @@ -8,6 +8,20 @@ type GetPaymentsArgs = import("lightning").GetPaymentsArgs type GetPendingPaymentsArgs = import("lightning").GetPendingPaymentsArgs type GetPendingPaymentsResult = import("lightning").GetPendingPaymentsResult +type ConfirmedPaymentResult = Extract< + GetPaymentsResult, + { payments: unknown } +>["payments"][0] +type PendingPaymentResult = Extract< + GetPendingPaymentsResult, + { payments: unknown } +>["payments"][0] +type FailedPaymentResult = Extract< + GetFailedPaymentsResult, + { payments: unknown } +>["payments"][0] +type PaymentResult = ConfirmedPaymentResult | PendingPaymentResult | FailedPaymentResult + type PaymentFnFactory = | import("lightning").AuthenticatedLightningMethod< GetFailedPaymentsArgs, From 947f4043cb4ecf7f810521589eb55ded60dfdc83 Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Thu, 9 Nov 2023 13:09:11 -0500 Subject: [PATCH 2/5] test: add alternate invoice creation --- core/api/test/bats/helpers/ln.bash | 14 ++++++++ core/api/test/bats/ln-receive.bats | 52 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/core/api/test/bats/helpers/ln.bash b/core/api/test/bats/helpers/ln.bash index 27a46870f3..e13931dffb 100644 --- a/core/api/test/bats/helpers/ln.bash +++ b/core/api/test/bats/helpers/ln.bash @@ -165,6 +165,20 @@ lnd_cli() { $@ } +lnd_start() { + synced_to_graph() { + is_synced="$(lnd_cli getinfo | jq -r '.synced_to_graph')" + [[ "$is_synced" == "true" ]] || exit 1 + } + + docker start "${COMPOSE_PROJECT_NAME}-lnd1-1" + retry 10 1 synced_to_graph +} + +lnd_stop() { + docker stop -t 0 "${COMPOSE_PROJECT_NAME}-lnd1-1" +} + lnd2_cli() { docker exec "${COMPOSE_PROJECT_NAME}-lnd2-1" \ lncli \ diff --git a/core/api/test/bats/ln-receive.bats b/core/api/test/bats/ln-receive.bats index 8e35714758..f4ab6427c8 100644 --- a/core/api/test/bats/ln-receive.bats +++ b/core/api/test/bats/ln-receive.bats @@ -404,3 +404,55 @@ usd_amount=50 # Check for settled retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" } + +@test "ln-receive: create invoices from alternate node" { + lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') + lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') + + token_name="$ALICE_TOKEN_NAME" + btc_wallet_name="$token_name.btc_wallet_id" + + # Generate invoice, it should be from lnd1 + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.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 + + destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" + [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 + + # Generate invoice after lnd1 stop, it should be from lnd2 + lnd_stop + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.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 + + destination_node="$(lnd2_cli decodepayreq $payment_request | jq -r '.destination')" + [[ "${destination_node}" == "${lnd2_pubkey}" ]] || exit 1 + + # Generate invoice after lnd1 start, it should be from lnd1 + lnd_start + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.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 + + destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" + [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 +} From 789d657a8b2f65ba67ff5eed33e1a0fbc9624a03 Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Thu, 9 Nov 2023 18:08:10 -0500 Subject: [PATCH 3/5] test: move tests to invoices --- core/api/test/bats/helpers/ln.bash | 9 +++-- core/api/test/bats/invoices.bats | 64 ++++++++++++++++++++++++------ core/api/test/bats/ln-receive.bats | 52 ------------------------ 3 files changed, 57 insertions(+), 68 deletions(-) diff --git a/core/api/test/bats/helpers/ln.bash b/core/api/test/bats/helpers/ln.bash index e13931dffb..e773663ff5 100644 --- a/core/api/test/bats/helpers/ln.bash +++ b/core/api/test/bats/helpers/ln.bash @@ -166,13 +166,14 @@ lnd_cli() { } lnd_start() { - synced_to_graph() { - is_synced="$(lnd_cli getinfo | jq -r '.synced_to_graph')" - [[ "$is_synced" == "true" ]] || exit 1 + started() { + state="$(lnd_cli state | jq -r '.state')" + is_synced="$(lnd_outside_cli getinfo | jq -r '.synced_to_graph')" + [[ "$state" == "SERVER_ACTIVE" && "$is_synced" == "true" ]] || exit 1 } docker start "${COMPOSE_PROJECT_NAME}-lnd1-1" - retry 10 1 synced_to_graph + retry 20 3 started } lnd_stop() { diff --git a/core/api/test/bats/invoices.bats b/core/api/test/bats/invoices.bats index 5d39f56343..9aa333d3ab 100644 --- a/core/api/test/bats/invoices.bats +++ b/core/api/test/bats/invoices.bats @@ -42,6 +42,58 @@ setup_file() { exec_graphql "$token_name" 'ln-usd-invoice-create' "$variables" } +teardown_file() { + stop_trigger + stop_server + stop_ws_server + stop_exporter +} + +setup() { + reset_redis +} + +@test "invoices: create invoices from alternate node" { + lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') + lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') + btc_amount=1000 + + token_name="$ALICE_TOKEN_NAME" + btc_wallet_name="$token_name.btc_wallet_id" + + # Generate invoice, it should be from lnd1 + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.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 + + destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" + [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 + + # Generate invoice after lnd1 stop, it should be from lnd2 + lnd_stop + exec_graphql "$token_name" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + lnd_start + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + destination_node="$(lnd2_cli decodepayreq $payment_request | jq -r '.destination')" + [[ "${destination_node}" == "${lnd2_pubkey}" ]] || exit 1 +} + @test "invoices: get invoices for account" { token_name="$ALICE_TOKEN_NAME" @@ -65,15 +117,3 @@ setup_file() { invoice_count="$(graphql_output '.data.me.defaultAccount.walletById.invoices.edges | length')" [[ "$invoice_count" -eq "2" ]] || exit 1 } - - -teardown_file() { - stop_trigger - stop_server - stop_ws_server - stop_exporter -} - -setup() { - reset_redis -} diff --git a/core/api/test/bats/ln-receive.bats b/core/api/test/bats/ln-receive.bats index f4ab6427c8..8e35714758 100644 --- a/core/api/test/bats/ln-receive.bats +++ b/core/api/test/bats/ln-receive.bats @@ -404,55 +404,3 @@ usd_amount=50 # Check for settled retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" } - -@test "ln-receive: create invoices from alternate node" { - lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') - lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') - - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - # Generate invoice, it should be from lnd1 - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg amount "$btc_amount" \ - '{input: {walletId: $wallet_id, amount: $amount}}' - ) - exec_graphql "$token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.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 - - destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" - [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 - - # Generate invoice after lnd1 stop, it should be from lnd2 - lnd_stop - exec_graphql "$token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.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 - - destination_node="$(lnd2_cli decodepayreq $payment_request | jq -r '.destination')" - [[ "${destination_node}" == "${lnd2_pubkey}" ]] || exit 1 - - # Generate invoice after lnd1 start, it should be from lnd1 - lnd_start - exec_graphql "$token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.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 - - destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" - [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 -} From 1a129ae0a6073823e269753b3a38026e49d287b7 Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Thu, 9 Nov 2023 19:01:51 -0500 Subject: [PATCH 4/5] fix: remove onchain lnd dep on lnd service creation --- core/api/src/services/lnd/index.ts | 18 ++++++----- core/api/test/bats/helpers/ln.bash | 4 +-- core/api/test/bats/invoices.bats | 48 +++++++++++++++--------------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/core/api/src/services/lnd/index.ts b/core/api/src/services/lnd/index.ts index 957a0b5d56..9d9ea936e2 100644 --- a/core/api/src/services/lnd/index.ts +++ b/core/api/src/services/lnd/index.ts @@ -96,10 +96,11 @@ export const LndService = (): ILightningService | LightningServiceError => { const defaultLnd = activeNode.lnd const defaultPubkey = activeNode.pubkey as Pubkey - const activeOnchainNode = getActiveOnchainLnd() - if (activeOnchainNode instanceof Error) return activeOnchainNode - - const defaultOnchainLnd = activeOnchainNode.lnd + const defaultOnchainLnd = () => { + const activeOnchainNode = getActiveOnchainLnd() + if (activeOnchainNode instanceof Error) return activeOnchainNode + return activeOnchainNode.lnd + } const isLocal = (pubkey: Pubkey): boolean | LightningServiceError => getLnds({ type: "offchain" }).some((item) => item.pubkey === pubkey) @@ -131,7 +132,7 @@ export const LndService = (): ILightningService | LightningServiceError => { pubkey?: Pubkey, ): Promise => { try { - const lndInstance = pubkey ? getLndFromPubkey({ pubkey }) : defaultOnchainLnd + const lndInstance = pubkey ? getLndFromPubkey({ pubkey }) : defaultOnchainLnd() if (lndInstance instanceof Error) return lndInstance const { chain_balance } = await getChainBalance({ lnd: lndInstance }) @@ -145,7 +146,7 @@ export const LndService = (): ILightningService | LightningServiceError => { pubkey?: Pubkey, ): Promise => { try { - const lndInstance = pubkey ? getLndFromPubkey({ pubkey }) : defaultOnchainLnd + const lndInstance = pubkey ? getLndFromPubkey({ pubkey }) : defaultOnchainLnd() if (lndInstance instanceof Error) return lndInstance const { pending_chain_balance } = await getPendingChainBalance({ lnd: lndInstance }) @@ -183,8 +184,11 @@ export const LndService = (): ILightningService | LightningServiceError => { // this is necessary for tests, otherwise `after` may be negative const after = Math.max(0, blockHeight - scanDepth) + const lnd = defaultOnchainLnd() + if (lnd instanceof Error) return lnd + const txs = await getChainTransactions({ - lnd: defaultOnchainLnd, + lnd, after, }) diff --git a/core/api/test/bats/helpers/ln.bash b/core/api/test/bats/helpers/ln.bash index e773663ff5..0c19b2e98c 100644 --- a/core/api/test/bats/helpers/ln.bash +++ b/core/api/test/bats/helpers/ln.bash @@ -168,12 +168,12 @@ lnd_cli() { lnd_start() { started() { state="$(lnd_cli state | jq -r '.state')" - is_synced="$(lnd_outside_cli getinfo | jq -r '.synced_to_graph')" + is_synced="$(lnd_cli getinfo | jq -r '.synced_to_graph')" [[ "$state" == "SERVER_ACTIVE" && "$is_synced" == "true" ]] || exit 1 } docker start "${COMPOSE_PROJECT_NAME}-lnd1-1" - retry 20 3 started + retry 10 5 started } lnd_stop() { diff --git a/core/api/test/bats/invoices.bats b/core/api/test/bats/invoices.bats index 9aa333d3ab..2b22ec0786 100644 --- a/core/api/test/bats/invoices.bats +++ b/core/api/test/bats/invoices.bats @@ -53,6 +53,30 @@ setup() { reset_redis } +@test "invoices: get invoices for account" { + token_name="$ALICE_TOKEN_NAME" + + exec_graphql "$token_name" 'invoices' '{"first": 3}' + + invoice_count="$(graphql_output '.data.me.defaultAccount.invoices.edges | length')" + [[ "$invoice_count" -eq "3" ]] || exit 1 +} + +@test "invoices: get invoices for wallet" { + token_name="$ALICE_TOKEN_NAME" + btc_wallet_name="$token_name.btc_wallet_id" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{walletId: $wallet_id, first: 2}' + ) + exec_graphql "$token_name" 'invoices-by-wallet' "$variables" + + invoice_count="$(graphql_output '.data.me.defaultAccount.walletById.invoices.edges | length')" + [[ "$invoice_count" -eq "2" ]] || exit 1 +} + @test "invoices: create invoices from alternate node" { lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') @@ -93,27 +117,3 @@ setup() { destination_node="$(lnd2_cli decodepayreq $payment_request | jq -r '.destination')" [[ "${destination_node}" == "${lnd2_pubkey}" ]] || exit 1 } - -@test "invoices: get invoices for account" { - token_name="$ALICE_TOKEN_NAME" - - exec_graphql "$token_name" 'invoices' '{"first": 3}' - - invoice_count="$(graphql_output '.data.me.defaultAccount.invoices.edges | length')" - [[ "$invoice_count" -eq "3" ]] || exit 1 -} - -@test "invoices: get invoices for wallet" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - '{walletId: $wallet_id, first: 2}' - ) - exec_graphql "$token_name" 'invoices-by-wallet' "$variables" - - invoice_count="$(graphql_output '.data.me.defaultAccount.walletById.invoices.edges | length')" - [[ "$invoice_count" -eq "2" ]] || exit 1 -} From a1758f1555ea832b9a00f10606c8942dcb4cfbac Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Tue, 14 Nov 2023 20:20:50 -0500 Subject: [PATCH 5/5] test: remove tests --- core/api/test/bats/helpers/ln.bash | 15 -------- core/api/test/bats/invoices.bats | 56 +++++------------------------- 2 files changed, 8 insertions(+), 63 deletions(-) diff --git a/core/api/test/bats/helpers/ln.bash b/core/api/test/bats/helpers/ln.bash index 0c19b2e98c..27a46870f3 100644 --- a/core/api/test/bats/helpers/ln.bash +++ b/core/api/test/bats/helpers/ln.bash @@ -165,21 +165,6 @@ lnd_cli() { $@ } -lnd_start() { - started() { - state="$(lnd_cli state | jq -r '.state')" - is_synced="$(lnd_cli getinfo | jq -r '.synced_to_graph')" - [[ "$state" == "SERVER_ACTIVE" && "$is_synced" == "true" ]] || exit 1 - } - - docker start "${COMPOSE_PROJECT_NAME}-lnd1-1" - retry 10 5 started -} - -lnd_stop() { - docker stop -t 0 "${COMPOSE_PROJECT_NAME}-lnd1-1" -} - lnd2_cli() { docker exec "${COMPOSE_PROJECT_NAME}-lnd2-1" \ lncli \ diff --git a/core/api/test/bats/invoices.bats b/core/api/test/bats/invoices.bats index 2b22ec0786..5d39f56343 100644 --- a/core/api/test/bats/invoices.bats +++ b/core/api/test/bats/invoices.bats @@ -42,17 +42,6 @@ setup_file() { exec_graphql "$token_name" 'ln-usd-invoice-create' "$variables" } -teardown_file() { - stop_trigger - stop_server - stop_ws_server - stop_exporter -} - -setup() { - reset_redis -} - @test "invoices: get invoices for account" { token_name="$ALICE_TOKEN_NAME" @@ -77,43 +66,14 @@ setup() { [[ "$invoice_count" -eq "2" ]] || exit 1 } -@test "invoices: create invoices from alternate node" { - lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') - lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') - btc_amount=1000 - - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - # Generate invoice, it should be from lnd1 - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg amount "$btc_amount" \ - '{input: {walletId: $wallet_id, amount: $amount}}' - ) - exec_graphql "$token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.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 - - destination_node="$(lnd_cli decodepayreq $payment_request | jq -r '.destination')" - [[ "${destination_node}" == "${lnd1_pubkey}" ]] || exit 1 - - # Generate invoice after lnd1 stop, it should be from lnd2 - lnd_stop - exec_graphql "$token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" - lnd_start - payment_request="$(echo $invoice | jq -r '.paymentRequest')" - [[ "${payment_request}" != "null" ]] || exit 1 - payment_hash="$(echo $invoice | jq -r '.paymentHash')" - [[ "${payment_hash}" != "null" ]] || exit 1 +teardown_file() { + stop_trigger + stop_server + stop_ws_server + stop_exporter +} - destination_node="$(lnd2_cli decodepayreq $payment_request | jq -r '.destination')" - [[ "${destination_node}" == "${lnd2_pubkey}" ]] || exit 1 +setup() { + reset_redis }