mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-10 06:43:00 +00:00
Merge pull request #2023 from PR0M3TH3AN/fix-webtorrent-webseed-regression-10274894627332192935
Fix WebTorrent webseed stream health check regression
This commit is contained in:
32 files changed
+1165
-1058
No files matched your search
@@ -3,7 +3,6 @@
|
||||
import { signEventWithPrivateKey } from "../publishHelpers.js";
|
||||
import { createPrivateKeyCipherClosures } from "../signerHelpers.js";
|
||||
import { ensureNostrTools, getCachedNostrTools } from "../toolkit.js";
|
||||
import { hexToBytes } from "../../utils/hex.js";
|
||||
import { normalizeActorKey } from "../watchHistory.js";
|
||||
|
||||
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
|
||||
@@ -31,7 +30,7 @@ async function resolvePublicKey(privateKey, pubkey) {
|
||||
|
||||
const tools = (await ensureNostrTools()) || getCachedNostrTools();
|
||||
if (tools?.getPublicKey && typeof tools.getPublicKey === "function") {
|
||||
const derived = tools.getPublicKey(hexToBytes(privateKey));
|
||||
const derived = tools.getPublicKey(privateKey);
|
||||
const normalized = normalizeActorKey(derived);
|
||||
if (normalized && HEX64_REGEX.test(normalized)) {
|
||||
return normalized;
|
||||
|
||||
+17
-26
@@ -130,7 +130,6 @@ import {
|
||||
summarizeDmEventForLog,
|
||||
} from "./dmDecryptDiagnostics.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
import { hexToBytes } from "../utils/hex.js";
|
||||
import { LRUCache } from "../utils/lruCache.js";
|
||||
import { updateConversationFromMessage, writeMessages } from "../storage/dmDb.js";
|
||||
import {
|
||||
@@ -1630,7 +1629,7 @@ export class NostrClient {
|
||||
if (!tools || typeof tools.getPublicKey !== "function") {
|
||||
throw new Error("Public key derivation is unavailable for remote signing.");
|
||||
}
|
||||
publicKey = tools.getPublicKey(hexToBytes(privateKey));
|
||||
publicKey = tools.getPublicKey(privateKey);
|
||||
}
|
||||
|
||||
if (!publicKey || !HEX64_REGEX.test(publicKey)) {
|
||||
@@ -2276,7 +2275,7 @@ export class NostrClient {
|
||||
if (!tools || typeof tools.getPublicKey !== "function") {
|
||||
throw new Error("Public key derivation is unavailable for the remote signer handshake.");
|
||||
}
|
||||
clientPublicKey = normalizeNostrPubkey(tools.getPublicKey(hexToBytes(clientPrivateKey)));
|
||||
clientPublicKey = normalizeNostrPubkey(tools.getPublicKey(clientPrivateKey));
|
||||
}
|
||||
|
||||
if (!clientPublicKey || !HEX64_REGEX.test(clientPublicKey)) {
|
||||
@@ -3441,7 +3440,7 @@ export class NostrClient {
|
||||
|
||||
let pubkey = "";
|
||||
try {
|
||||
pubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
|
||||
pubkey = getPublicKey(normalizedPrivateKey);
|
||||
} catch (error) {
|
||||
let retrySuccess = false;
|
||||
try {
|
||||
@@ -3552,7 +3551,7 @@ export class NostrClient {
|
||||
|
||||
let pubkey = "";
|
||||
try {
|
||||
pubkey = getPublicKey(hexToBytes(privateKey));
|
||||
pubkey = getPublicKey(privateKey);
|
||||
} catch (error) {
|
||||
const failure = new Error("Failed to derive the public key.");
|
||||
failure.cause = error;
|
||||
@@ -3596,7 +3595,7 @@ export class NostrClient {
|
||||
throw new Error("Public key derivation is unavailable.");
|
||||
}
|
||||
try {
|
||||
normalizedPubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
|
||||
normalizedPubkey = getPublicKey(normalizedPrivateKey);
|
||||
} catch (error) {
|
||||
const failure = new Error("Failed to derive the public key.");
|
||||
failure.cause = error;
|
||||
@@ -3734,7 +3733,7 @@ export class NostrClient {
|
||||
throw new Error("Public key derivation is unavailable.");
|
||||
}
|
||||
try {
|
||||
normalizedPubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
|
||||
normalizedPubkey = getPublicKey(normalizedPrivateKey);
|
||||
} catch (error) {
|
||||
const failure = new Error("Failed to derive the public key.");
|
||||
failure.cause = error;
|
||||
@@ -7651,7 +7650,6 @@ export class NostrClient {
|
||||
|
||||
const toProcess = eventBuffer;
|
||||
eventBuffer = [];
|
||||
const videosNeedingMetadata = [];
|
||||
|
||||
for (const evt of toProcess) {
|
||||
try {
|
||||
@@ -7708,30 +7706,23 @@ export class NostrClient {
|
||||
this.activeMap.set(activeKey, video);
|
||||
onVideo(video); // Trigger the callback that re-renders
|
||||
|
||||
// Defer NIP-71 fetch for batching
|
||||
videosNeedingMetadata.push(video);
|
||||
// Fetch NIP-71 metadata (categorization tags) in the background
|
||||
this.populateNip71MetadataForVideos([video])
|
||||
.then(() => {
|
||||
this.applyRootCreatedAt(video);
|
||||
})
|
||||
.catch((error) => {
|
||||
devLogger.warn(
|
||||
"[nostr] Failed to hydrate NIP-71 metadata for live video:",
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
devLogger.error("[subscribeVideos] Error processing event:", err);
|
||||
}
|
||||
}
|
||||
|
||||
if (videosNeedingMetadata.length > 0) {
|
||||
// Fetch NIP-71 metadata (categorization tags) in the background
|
||||
this.populateNip71MetadataForVideos(videosNeedingMetadata)
|
||||
.then(() => {
|
||||
for (const video of videosNeedingMetadata) {
|
||||
this.applyRootCreatedAt(video);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
devLogger.warn(
|
||||
"[nostr] Failed to hydrate NIP-71 metadata for live video batch:",
|
||||
error,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Persist processed events after each flush so reloads warm quickly.
|
||||
this.saveLocalData("subscribeVideos:flush");
|
||||
};
|
||||
|
||||
+3
-10
@@ -25,7 +25,6 @@ import {
|
||||
assertAnyRelayAccepted as defaultAssertAnyRelayAccepted,
|
||||
} from "../nostrPublish.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
import { hexToBytes } from "../utils/hex.js";
|
||||
import { Nip46RequestQueue, NIP46_PRIORITY } from "./nip46Queue.js";
|
||||
|
||||
export const HEX64_REGEX = /^[0-9a-f]{64}$/i;
|
||||
@@ -1072,10 +1071,7 @@ function resolveAvailableNip46Ciphers(
|
||||
typeof nip44v2GetConversationKey === "function"
|
||||
) {
|
||||
registerCipher("nip44.v2", () => {
|
||||
const conversationKey = nip44v2GetConversationKey(
|
||||
hexToBytes(privateKey),
|
||||
remotePubkey,
|
||||
);
|
||||
const conversationKey = nip44v2GetConversationKey(privateKey, remotePubkey);
|
||||
|
||||
if (!conversationKey) {
|
||||
throw new Error("Failed to derive a nip44 conversation key for remote signing.");
|
||||
@@ -1099,10 +1095,7 @@ function resolveAvailableNip46Ciphers(
|
||||
typeof nip44GetConversationKey === "function"
|
||||
) {
|
||||
registerCipher("nip44", () => {
|
||||
const conversationKey = nip44GetConversationKey(
|
||||
hexToBytes(privateKey),
|
||||
remotePubkey,
|
||||
);
|
||||
const conversationKey = nip44GetConversationKey(privateKey, remotePubkey);
|
||||
|
||||
if (!conversationKey) {
|
||||
throw new Error("Failed to derive a nip44 conversation key for remote signing.");
|
||||
@@ -1501,7 +1494,7 @@ export class Nip46RpcClient {
|
||||
if (!tools || typeof tools.getPublicKey !== "function") {
|
||||
throw new Error("Public key derivation is unavailable.");
|
||||
}
|
||||
this.clientPublicKey = tools.getPublicKey(hexToBytes(this.clientPrivateKey));
|
||||
this.clientPublicKey = tools.getPublicKey(this.clientPrivateKey);
|
||||
if (!this.clientPublicKey || !HEX64_REGEX.test(this.clientPublicKey)) {
|
||||
throw new Error("Failed to derive a valid public key for the remote signer session.");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
getCachedNostrTools,
|
||||
readToolkitFromScope,
|
||||
} from "./toolkit.js";
|
||||
import { hexToBytes } from "../utils/hex.js";
|
||||
import { DEFAULT_NIP07_PERMISSION_METHODS } from "./nip07Permissions.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
import { logRebroadcastCountFailure } from "./countDiagnostics.js";
|
||||
@@ -135,7 +134,7 @@ export function signEventWithPrivateKey(event, privateKey) {
|
||||
throw new Error("Missing signing primitives");
|
||||
}
|
||||
|
||||
const finalized = finalizeFn(prepared, hexToBytes(normalizedKey));
|
||||
const finalized = finalizeFn(prepared, normalizedKey);
|
||||
if (
|
||||
!finalized ||
|
||||
typeof finalized.id !== "string" ||
|
||||
|
||||
@@ -9,21 +9,3 @@ export function normalizeHexString(value) {
|
||||
|
||||
export const normalizeHexId = normalizeHexString;
|
||||
export const normalizeHexPubkey = normalizeHexString;
|
||||
|
||||
export function hexToBytes(hex) {
|
||||
if (typeof hex !== "string") {
|
||||
throw new TypeError("hexToBytes: expected string, got " + typeof hex);
|
||||
}
|
||||
const normalized = hex.trim();
|
||||
if (normalized.length % 2) throw new Error("hex string must have even length");
|
||||
const array = new Uint8Array(normalized.length / 2);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const j = i * 2;
|
||||
const byte = parseInt(normalized.substring(j, j + 2), 16);
|
||||
if (Number.isNaN(byte) || byte < 0) {
|
||||
throw new Error("Invalid hex string");
|
||||
}
|
||||
array[i] = byte;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
+8
-6
@@ -346,23 +346,25 @@ export class TorrentClient {
|
||||
|
||||
torrent.once("error", (err) => {
|
||||
const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0)));
|
||||
const webseedOnly = peers === 0 && hasWebSeed;
|
||||
finalize({
|
||||
healthy: false,
|
||||
reason: "error",
|
||||
healthy: webseedOnly,
|
||||
reason: webseedOnly ? "webseed" : "error",
|
||||
error: toError(err),
|
||||
peers,
|
||||
webseedOnly: peers === 0 && hasWebSeed,
|
||||
webseedOnly,
|
||||
});
|
||||
});
|
||||
|
||||
if (safeTimeout > 0) {
|
||||
timeoutId = setTimeout(() => {
|
||||
const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0)));
|
||||
const webseedOnly = peers === 0 && hasWebSeed;
|
||||
finalize({
|
||||
healthy: false,
|
||||
healthy: webseedOnly,
|
||||
peers,
|
||||
reason: "timeout",
|
||||
webseedOnly: peers === 0 && hasWebSeed,
|
||||
reason: webseedOnly ? "webseed" : "timeout",
|
||||
webseedOnly,
|
||||
});
|
||||
}, safeTimeout);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user