workaround for lnd rescan bug
This commit is contained in:
parent
ce94b316fb
commit
3b8ec65c67
6 changed files with 92 additions and 2 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#LND_ADDRESS=127.0.0.1:10009
|
||||
#LND_CERT_PATH=~/.lnd/tls.cert
|
||||
#LND_MACAROON_PATH=~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon
|
||||
#LND_LOG_DIR=~/.lnd/logs/bitcoin/mainnet/lnd.log
|
||||
|
||||
#BOOTSTRAP_PEER
|
||||
# A trusted peer that will hold a node-level account until channel automation becomes affordable
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ get_log_info() {
|
|||
LOG_DIR="$USER_HOME/lightning_pub/logs"
|
||||
DATA_DIR="$USER_HOME/lightning_pub/"
|
||||
START_TIME=$(date +%s)
|
||||
MAX_WAIT_TIME=120 # Maximum wait time in seconds
|
||||
MAX_WAIT_TIME=360 # Maximum wait time in seconds (6 minutes)
|
||||
WAIT_INTERVAL=5 # Time to wait between checks in seconds
|
||||
|
||||
log "Checking wallet status... This may take a moment."
|
||||
|
|
@ -50,7 +50,24 @@ get_log_info() {
|
|||
START_TIME=$(date +%s)
|
||||
while [ $(($(date +%s) - START_TIME)) -lt $MAX_WAIT_TIME ]; do
|
||||
latest_entry=$(grep -E "unlocker >> (the wallet is already unlocked|created wallet with pub:|unlocked wallet with pub)" "$latest_unlocker_log" | tail -n 1)
|
||||
|
||||
# Show dynamic header sync progress if available from unlocker logs
|
||||
progress_line=$(grep -E "LND header sync [0-9]+% \(height=" "$latest_unlocker_log" | tail -n 1)
|
||||
if [ -n "$progress_line" ]; then
|
||||
percent=$(echo "$progress_line" | sed -E 's/.*LND header sync ([0-9]+)%.*/\1/')
|
||||
if [[ "$percent" =~ ^[0-9]+$ ]]; then
|
||||
bar_len=30
|
||||
filled=$((percent*bar_len/100))
|
||||
if [ $filled -gt $bar_len ]; then filled=$bar_len; fi
|
||||
empty=$((bar_len-filled))
|
||||
filled_bar=$(printf '%*s' "$filled" | tr ' ' '#')
|
||||
empty_bar=$(printf '%*s' "$empty" | tr ' ' ' ')
|
||||
echo -ne "Header sync: [${filled_bar}${empty_bar}] ${percent}%\r"
|
||||
fi
|
||||
fi
|
||||
if [ -n "$latest_entry" ]; then
|
||||
# End the progress line cleanly
|
||||
echo ""
|
||||
break
|
||||
fi
|
||||
sleep $WAIT_INTERVAL
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ else
|
|||
# Only start services if it was a fresh install or an upgrade.
|
||||
if [ "$pub_upgrade_status" -eq 0 ] || [ "$pub_upgrade_status" -eq 100 ]; then
|
||||
log "Starting services..."
|
||||
log "Note: LND may take several minutes to sync block headers depending on network conditions."
|
||||
touch /tmp/pub_install_timestamp
|
||||
start_services $lnd_status $pub_upgrade_status || log_error "Failed to start services" 1
|
||||
get_log_info || log_error "Failed to get log info" 1
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@ export const LoadLndSettingsFromEnv = (): LndSettings => {
|
|||
const lndAddr = process.env.LND_ADDRESS || "127.0.0.1:10009"
|
||||
const lndCertPath = process.env.LND_CERT_PATH || resolveHome("/.lnd/tls.cert")
|
||||
const lndMacaroonPath = process.env.LND_MACAROON_PATH || resolveHome("/.lnd/data/chain/bitcoin/mainnet/admin.macaroon")
|
||||
const lndLogDir = process.env.LND_LOG_DIR || resolveHome("/.lnd/logs/bitcoin/mainnet/lnd.log")
|
||||
const feeRateBps = EnvCanBeInteger("OUTBOUND_MAX_FEE_BPS", 60)
|
||||
const feeRateLimit = feeRateBps / 10000
|
||||
const feeFixedLimit = EnvCanBeInteger("OUTBOUND_MAX_FEE_EXTRA_SATS", 100)
|
||||
const mockLnd = EnvCanBeBoolean("MOCK_LND")
|
||||
return { mainNode: { lndAddr, lndCertPath, lndMacaroonPath }, feeRateLimit, feeFixedLimit, feeRateBps, mockLnd }
|
||||
return { mainNode: { lndAddr, lndCertPath, lndMacaroonPath }, lndLogDir, feeRateLimit, feeFixedLimit, feeRateBps, mockLnd }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export type NodeSettings = {
|
|||
}
|
||||
export type LndSettings = {
|
||||
mainNode: NodeSettings
|
||||
lndLogDir: string
|
||||
feeRateLimit: number
|
||||
feeFixedLimit: number
|
||||
feeRateBps: number
|
||||
|
|
@ -15,6 +16,7 @@ export type LndSettings = {
|
|||
otherNode?: NodeSettings
|
||||
thirdNode?: NodeSettings
|
||||
}
|
||||
|
||||
type TxOutput = {
|
||||
hash: string
|
||||
index: number
|
||||
|
|
|
|||
|
|
@ -95,8 +95,76 @@ export class Unlocker {
|
|||
return { ln, pub: infoAfter.pub, action: 'unlocked' }
|
||||
}
|
||||
|
||||
private waitForLndSync = async (timeoutSeconds: number): Promise<void> => {
|
||||
const lndLogPath = this.settings.lndSettings.lndLogDir;
|
||||
if (this.settings.lndSettings.mockLnd) {
|
||||
this.log("MOCK_LND set, skipping header sync wait.");
|
||||
return;
|
||||
}
|
||||
|
||||
let targetHeight = 0;
|
||||
this.log(`Waiting for LND to sync headers (timeout: ${timeoutSeconds}s). Log: ${lndLogPath} (discovering target height...)`);
|
||||
|
||||
let lastPercentReported = -1;
|
||||
const startTime = Date.now();
|
||||
const checkLog = async (resolve: () => void, reject: (reason?: any) => void) => {
|
||||
const elapsedTime = (Date.now() - startTime) / 1000;
|
||||
if (elapsedTime > timeoutSeconds) {
|
||||
return reject(new Error("Timed out waiting for LND to sync."));
|
||||
}
|
||||
|
||||
try {
|
||||
if (fs.existsSync(lndLogPath)) {
|
||||
const logContent = fs.readFileSync(lndLogPath, 'utf8');
|
||||
|
||||
if (logContent.includes("Fully caught up with cfheaders")) {
|
||||
this.log("LND sync complete.");
|
||||
return resolve();
|
||||
}
|
||||
|
||||
// If target height isn't known yet, try to derive it from the log
|
||||
if (targetHeight === 0) {
|
||||
const targetMatch = [...logContent.matchAll(/Syncing to block height\s+(\d+)\s+from peer/gi)];
|
||||
if (targetMatch.length > 0) {
|
||||
const lastTarget = targetMatch[targetMatch.length - 1];
|
||||
const parsedTarget = Number.parseInt(lastTarget[1], 10);
|
||||
if (!Number.isNaN(parsedTarget) && parsedTarget > 0) {
|
||||
targetHeight = parsedTarget;
|
||||
this.log(`Detected target header height: ${targetHeight}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse latest reported height: look for "height=NNNN" occurrences
|
||||
const matches = [...logContent.matchAll(/height=(\d+)/g)];
|
||||
if (matches.length > 0) {
|
||||
const lastMatch = matches[matches.length - 1];
|
||||
const currentHeight = Number.parseInt(lastMatch[1], 10);
|
||||
if (!Number.isNaN(currentHeight) && currentHeight > 0 && targetHeight > 0) {
|
||||
const percent = Math.min(99, Math.max(0, Math.floor((Math.min(currentHeight, targetHeight) * 100) / targetHeight)));
|
||||
// Report only on first run and on >=5% increments to reduce noise
|
||||
if (lastPercentReported === -1 || percent >= lastPercentReported + 5) {
|
||||
this.log(`LND header sync ${percent}% (height=${currentHeight}/${targetHeight})`);
|
||||
lastPercentReported = percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Log file might not exist yet, which is fine.
|
||||
}
|
||||
|
||||
setTimeout(() => checkLog(resolve, reject), 3000);
|
||||
};
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
checkLog(resolve, reject);
|
||||
});
|
||||
}
|
||||
|
||||
InitFlow = async (lndCert: Buffer) => {
|
||||
this.log("macaroon not found, creating wallet...")
|
||||
await this.waitForLndSync(300); // Wait up to 5 minutes
|
||||
const unlocker = this.GetUnlockerClient(lndCert)
|
||||
const { plaintextSeed, encryptedSeed } = await this.genSeed(unlocker)
|
||||
return this.initWallet(lndCert, unlocker, { plaintextSeed, encryptedSeed })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue