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

Bump channel force closure #1433

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions ios/LndMobile/Lnd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ open class Lnd {
"VerifyMessage": { bytes, cb in LndmobileVerifyMessage(bytes, cb) },
"SignMessage": { bytes, cb in LndmobileSignMessage(bytes, cb) },
"SignerSignMessage": { bytes, cb in LndmobileSignerSignMessage(bytes, cb) },
"WalletKitListSweeps": { bytes, cb in LndmobileWalletKitListSweeps(bytes, cb) },

// autopilot
"AutopilotStatus": { bytes, cb in LndmobileAutopilotStatus(bytes, cb) },
Expand Down
63 changes: 62 additions & 1 deletion src/components/PendingChannelCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Long from "long";
import BigNumber from "bignumber.js";

import { style } from "./ChannelCard";
import { lnrpc } from "../../proto/lightning";
import { lnrpc, walletrpc } from "../../proto/lightning";
import { blixtTheme } from "../native-base-theme/variables/commonColor";
import { useStoreActions, useStoreState } from "../state/store";
import { identifyService, lightningServices } from "../utils/lightning-services";
Expand All @@ -16,6 +16,7 @@ import { getUnitNice, valueBitcoin, valueFiat } from "../utils/bitcoin-units";
import { useTranslation } from "react-i18next";
import { namespaces } from "../i18n/i18n.constants";
import { Alert } from "../utils/alert";
import { pendingSweeps } from "../lndmobile/wallet";

const dataLossChannelState = "ChanStatusLocalDataLoss|ChanStatusRestored";

Expand Down Expand Up @@ -98,6 +99,54 @@ export const PendingChannelCard = ({ channel, type, alias }: IPendingChannelCard
);
};

const dragForceCloseAnchor = async (
channel: lnrpc.PendingChannelsResponse.IWaitingCloseChannel,
) => {
Alert.prompt(t("channel.bumpFee"), t("channel.bumpFeeAlerts.enterFeeRate"), [
{
text: t("buttons.cancel", { ns: namespaces.common }),
style: "cancel",
onPress: () => {},
},
{
text: "OK",
onPress: async (feeRate) => {
if (!feeRate) {
Alert.alert(t("channel.bumpFeeAlerts.missingFeeRate"));
return;
}

const feeRateNumber = Number.parseInt(feeRate);

// Follows anchor sweep code in bumpForceCloseFee.go in lnd/cmd/lncli/walletrpc_active.go

//& Fetch waiting close channel commitments.
const sweeps = await pendingSweeps();

//& Retrieve pending sweeps.
const commitments = [channel.commitments?.localTxid, channel.commitments?.remoteTxid];

//& Match pending sweeps with commitments of the channel for which a bump
//& is requested and bump their fees.
for (const sweep of sweeps.pendingSweeps) {
//& Only bump anchor sweeps.
if (sweep.witnessType !== walletrpc.WitnessType.COMMITMENT_ANCHOR) {
continue;
}

if (commitments.includes(sweep.outpoint?.txidStr)) {
await bumpFee({
txid: sweep.outpoint?.txidStr ?? "",
index: sweep.outpoint?.outputIndex ?? 0,
feeRate: feeRateNumber,
});
}
}
},
},
]);
};

const bumpChannelFee = async (channel: lnrpc.PendingChannelsResponse.IPendingOpenChannel) => {
if (!channel.channel || !channel.channel.channelPoint) {
Alert.alert(t("msg.error", { ns: namespaces.common }));
Expand Down Expand Up @@ -391,6 +440,18 @@ export const PendingChannelCard = ({ channel, type, alias }: IPendingChannelCard
</Left>
</Row>
)}
<Row style={{ width: "100%" }}>
<Left>
<Button
style={{ marginTop: 14 }}
danger={true}
small={true}
onPress={() => dragForceCloseAnchor(channel)}
>
<Text style={{ fontSize: 8 }}>{t("channel.bumpFee")}</Text>
</Button>
</Left>
</Row>
</>
)}
{type === "FORCE_CLOSING" && (
Expand Down
17 changes: 16 additions & 1 deletion src/lndmobile/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as base64 from "base64-js";

import { sendCommand, sendStreamCommand, decodeStreamResult } from "./utils";
import { stringToUint8Array } from "../utils";
import { lnrpc, signrpc } from "../../proto/lightning";
import { lnrpc, signrpc, walletrpc } from "../../proto/lightning";

/**
* @throws
Expand Down Expand Up @@ -156,6 +156,21 @@ export const signMessage = async (keyFamily: number, keyIndex: number, msg: Uint
return response;
};


/**
* @throws
*/
export const pendingSweeps = async (): Promise<walletrpc.PendingSweepsResponse> => {
const response = await sendCommand<walletrpc.IPendingSweepsRequest, walletrpc.PendingSweepsRequest, walletrpc.PendingSweepsResponse>({
request: walletrpc.PendingSweepsRequest,
response: walletrpc.PendingSweepsResponse,
method: "WalletKitPendingSweeps",
options: {
},
});
return response;
};

// TODO exception?
// TODO move to a more appropriate file?
export const subscribeInvoices = async (): Promise<string> => {
Expand Down
15 changes: 14 additions & 1 deletion src/windows/InitProcess/DEV_Commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
getTransaction,
getTransactions,
} from "../../storage/database/transaction";
import { genSeed, initWallet, signMessage } from "../../lndmobile/wallet";
import { genSeed, initWallet, pendingSweeps, signMessage } from "../../lndmobile/wallet";
import { getPin, getWalletPassword } from "../../storage/keystore";
import { lnrpc, routerrpc } from "../../../proto/lightning";
import { modifyStatus, queryScores, status } from "../../lndmobile/autopilot";
Expand All @@ -71,6 +71,7 @@ import { blixtTheme } from "../../native-base-theme/variables/commonColor";
import { generateSecureRandom } from "react-native-securerandom";
import { localNotification } from "../../utils/push-notification";
import { sendCommand } from "../../lndmobile/utils";
import { getCFilter } from "../../lndmobile/neutrino";

let iCloudStorage: any;
console.log(PLATFORM);
Expand Down Expand Up @@ -145,6 +146,17 @@ export default function DEV_Commands({ navigation, continueCallback }: IProps) {
</>
)}
<Text style={{ width: "100%" }}>Random:</Text>
<Button
small
onPress={async () => {
Alert.prompt("Compact filter", undefined, async (hash) => {
const filter = await getCFilter(hash);
Alert.alert(filter.filter.byteLength.toString());
});
}}
>
<Text style={styles.buttonText}>getCFilter size</Text>
</Button>
<Button
small
onPress={async () => {
Expand Down Expand Up @@ -1282,6 +1294,7 @@ export default function DEV_Commands({ navigation, continueCallback }: IProps) {
["getNetworkInfo", getNetworkInfo],
["getTransactions", getTransactionsOnchain],
["closedChannels", closedChannels],
["pendingSweeps", pendingSweeps],
].map(([name, f], i) => {
return (
<Button
Expand Down
Loading