@decentnetwork/peer 0.1.77 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compat/filetransfer.js +17 -4
- package/package.json +1 -1
|
@@ -751,8 +751,7 @@ export class FileTransferManager {
|
|
|
751
751
|
// so a dup-ack burst can't storm). No window backoff: loss ≠ congestion.
|
|
752
752
|
st.lastResendMs = nowMs();
|
|
753
753
|
st.lastLossMs = nowMs(); // the path is lossy → turn adaptive FEC on
|
|
754
|
-
|
|
755
|
-
st.nextSend = st.acked;
|
|
754
|
+
this.#rewindRetransmit(st);
|
|
756
755
|
}
|
|
757
756
|
if (st.acked >= st.size) {
|
|
758
757
|
this.#completeSend(friendId, st);
|
|
@@ -760,6 +759,21 @@ export class FileTransferManager {
|
|
|
760
759
|
}
|
|
761
760
|
void this.#pump(friendId, st);
|
|
762
761
|
}
|
|
762
|
+
// Rewind for a go-back-N retransmit: move the send cursor back to the ack point
|
|
763
|
+
// AND rewind the FEC high-water mark so the re-sent blocks get FRESH parity.
|
|
764
|
+
// Without the parity rewind a lossy TAIL freezes forever — re-sending the
|
|
765
|
+
// region drops new chunks faster than it fills the old holes, and the receiver
|
|
766
|
+
// has no parity to recover them locally (parity was emitted once, long gone).
|
|
767
|
+
// Re-emitting parity lets the receiver FEC-recover the holes, so the tail
|
|
768
|
+
// converges instead of stalling at 93% (observed on 100 MB+ files).
|
|
769
|
+
#rewindRetransmit(st) {
|
|
770
|
+
if (st.nextSend > st.acked)
|
|
771
|
+
st.nextSend = st.acked;
|
|
772
|
+
const ackBlock = Math.floor(st.acked / MAX_FILE_DATA_SIZE / FEC_K);
|
|
773
|
+
if (ackBlock - 1 < st.parityHighBlock)
|
|
774
|
+
st.parityHighBlock = ackBlock - 1;
|
|
775
|
+
st.lastLossMs = nowMs(); // keep FEC ON so the re-emit actually fires
|
|
776
|
+
}
|
|
763
777
|
// Single send loop. Awaits each send so net_crypto / the UDP socket applies
|
|
764
778
|
// backpressure (fire-and-forget blasted the whole window into the macOS UDP
|
|
765
779
|
// buffer at once → systematic overflow/drops the retransmit couldn't dig out
|
|
@@ -803,8 +817,7 @@ export class FileTransferManager {
|
|
|
803
817
|
st.cwnd = Math.max(CWND_MIN_CHUNKS, Math.floor(st.cwnd / 2));
|
|
804
818
|
st.lastAckAdvanceMs = nowMs();
|
|
805
819
|
st.lastResendMs = nowMs();
|
|
806
|
-
|
|
807
|
-
st.nextSend = st.acked; // go-back-N
|
|
820
|
+
this.#rewindRetransmit(st); // go-back-N + re-emit tail parity
|
|
808
821
|
void this.#pump(friendId, st);
|
|
809
822
|
}, WATCHDOG_MS);
|
|
810
823
|
if (typeof st.timer.unref === "function")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.78",
|
|
4
4
|
"description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|