Skip to content

fix(amulegui): skip INC_UPDATE tag for unknown file ID when identifying metadata was suppressed - #819

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/808-incomplete-inc-update
Jun 2, 2026
Merged

fix(amulegui): skip INC_UPDATE tag for unknown file ID when identifying metadata was suppressed#819
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/808-incomplete-inc-update

Conversation

@got3nks

@got3nks got3nks commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #810 — same underlying #808 ghost-entry symptom via a second code path that the original guard doesn't catch.

The bug

CEC_SharedFile_Tag runs each metadata field through a per-connection CValueMap which suppresses tags whose value hasn't changed since the last cached send. On an EC_DETAIL_INC_UPDATE reply for a file ID amulegui has no record of, the server may already have cached and suppressed EC_TAG_PARTFILE_HASH / EC_TAG_PARTFILE_NAME / EC_TAG_PARTFILE_SIZE_FULL. The tag still carries the statistical child tags (request count, accept count, transferred bytes, AICH master hash, priority...) so the HasChildTags() guard added in #810 lets it through, but CKnownFile(tag) then reads empty hash + empty name + zero size via GetTagByNameSafe and produces the same "0-byte unnamed" ghost entry.

This is exactly what Stoatwblr reported on #808 after #810 had already landed:

Same issue as originally — these are only occurring in the main filestore area where 2 layers of new directories have been created [...] Updatesharedir script doesn't add XYZ/ABC/ to the scan list

The "2-layer deep" correlation is indirect — those are the directories the updatesharedir script added new entries for in the current reload shared round, so they're exactly the ones whose ECIDs amulegui has no record of yet, and the server-side CValueMap may already have suppressed the identity fields for those ECIDs from earlier traffic.

The fix

Same shape as the #810 guard, just looking at a different signal: the new-item path in CKnownFilesRem::ProcessUpdate now also bails out when the tag is missing EC_TAG_PARTFILE_HASH — the canonical identity tag — and logs on logEC. A subsequent full-state poll or the existing entry-mismatch recovery puts the file in correctly once the identifying metadata is back on the wire.

 if (!tag->HasChildTags()) {
     AddDebugLogLineN(logEC,
         CFormat(wxT("EC: alive-marker for unknown file ID %u; ignoring.")) % id);
     continue;
 }
+if (tag->GetTagByName(EC_TAG_PARTFILE_HASH) == NULL) {
+    AddDebugLogLineN(logEC,
+        CFormat(wxT("EC: incomplete INC_UPDATE tag (no PARTFILE_HASH) for unknown file ID %u; ignoring.")) % id);
+    continue;
+}
 CKnownFile * newFile;

Net change: +24 lines (one new guard + a comment explaining the suppression mechanism so future readers don't have to re-derive it).

Refs #808 (alive-marker variant of the same bug was #810).

…ng metadata was suppressed (amule-project#808 follow-up)

amule-project#810 plugged the first variant of the amule-project#808 ghost-entry pattern --
an EC_TAG_KNOWNFILE alive-marker tag with no children arriving for
a file ID amulegui has no record of.

A second variant with identical symptoms remains.
CEC_SharedFile_Tag (ECSpecialCoreTags.cpp:221) runs each metadata
field through a per-connection CValueMap (ECSpecialTags.h:59),
which suppresses tags whose value hasn't changed since the last
cached send. On EC_DETAIL_INC_UPDATE for a file ID amulegui hasn't
seen yet, the server may already have cached + suppressed
EC_TAG_PARTFILE_HASH / _NAME / _SIZE_FULL -- so the tag still
carries plenty of statistical children (request count, accept
count, transferred bytes, AICH masterhash, priority...) and the
HasChildTags() guard added in amule-project#810 lets it through, but
CKnownFile(tag) then reads empty hash + empty name + zero size via
GetTagByNameSafe and produces the same "0-byte unnamed" ghost
entry Stoatwblr reported.

Defensive check on the new-item path in CKnownFilesRem::Process
Update: if the tag is missing EC_TAG_PARTFILE_HASH (the canonical
identity tag), log on logEC and skip. The next full-state poll or
the existing entry-mismatch recovery path picks the file up
correctly once the server-side cache invalidation puts the
identifying metadata back on the wire.

Triggered in the wild by Stoatwblr's bulk `updatesharedir` /
`reload shared` script: amuled adds files to its shareset, the
INC_UPDATE diff to amulegui includes them as new entries, but
the per-(connection, ECID) value-map cache may already have
suppressed the identity fields, so the ghost entry pattern fires
once per affected file.

Refs amule-project#808 (amule-project#810 covered the alive-marker variant of the same bug).
@mrjimenez
mrjimenez merged commit 7760854 into amule-project:master Jun 2, 2026
7 checks passed
@got3nks
got3nks deleted the fix/808-incomplete-inc-update branch June 3, 2026 14:16
got3nks added a commit to got3nks/amule that referenced this pull request Jun 4, 2026
…ndex

Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(amule-project#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg
  amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796
  (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths).

- Bug Fixes & Stability: post-amule-project#744 fixes including EC notification
  leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728),
  amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760),
  PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788,
  amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756),
  Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833,
  amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR
  (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for
  date+version drift (amule-project#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
got3nks added a commit to got3nks/amule that referenced this pull request Jun 4, 2026
…ndex

Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(amule-project#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg
  amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796
  (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths).

- Bug Fixes & Stability: post-amule-project#744 fixes including EC notification
  leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728),
  amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760),
  PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788,
  amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756),
  Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833,
  amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR
  (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for
  date+version drift (amule-project#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
mrjimenez pushed a commit that referenced this pull request Jun 4, 2026
Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for #785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), #794 (.dmg
  amuleweb path), #789 (<OS>-<arch> artifact naming), #780 / #796
  (Windows DPI + comctl32 manifest), #784 (FHS share/amule paths).

- Bug Fixes & Stability: post-#744 fixes including EC notification
  leak (#797), big-library scaling (#736, #840 superseding #728),
  amulegui ghost entries (#810, #819, #841, #824, #830, #760),
  PartFile early hash (#762), server protocol fixes (#835, #788,
  #721, #787), crypto stream UB (#779), UAF prevention (#756),
  Kad rotation (#795, #799/#805), GTK warning silencing (#833,
  #826/#836), and the clang-tidy worklist (#770, #772-#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (#753/#754/#776), Galician (#763), Slovenian (#771), pt-BR
  (#768/#775/#812), French (#811), plus man-page tooling for
  date+version drift (#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (#817/#818/#821/#828/#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with #746-#845 + #841.
got3nks added a commit to got3nks/amule that referenced this pull request Jun 5, 2026
…_FILES / GET_DLOAD_QUEUE

The EC skip-unchanged opt-in (93a0676 "EC skip-unchanged (4/5)")
gates the per-file emit on `m_ecGen <= ec_threshold` in three
handlers. For unchanged files the server either emits a childless
alive-marker tag (legacy clients) or skips silently (partial-update
clients). Both shortcuts assume the client has previously received
the ECID with full detail. If it hasn't, the alive marker
constructs a ghost CKnownFile from an empty tag (amule-project#810 surface) and
the silent skip leaves the file invisible. The CValueMap-driven
identity suppression on subsequent emissions extends the surface to
INC_UPDATE tags that have children but no identifying fields (amule-project#819
surface).

The amulegui-side guards in amule-project#810 and amule-project#819 cover that client
specifically. Other legacy EC consumers — amuleweb, amulecmd, and
third-party clients — have no analogous guard and silently lose
newly-shared files until restart.

Fix at the source: track per-connection, per-handler ECIDs that
have been sent with full detail. Gate the alive-marker / silent-
skip shortcut on membership in that set. Files the client hasn't
seen fall through to full-detail emission unconditionally, and the
emission populates the per-connection CObjTagMap (so subsequent
INC_UPDATE diffs work) and inserts into the new sent-with-detail
set.

Three handlers, three sets — one per request path because each
handler has its own `m_lastEcGenSeen*` cadence.

Memory cost: bounded by alive-file ECID count per connection
(~360 KB at 91k files; insignificant). Never pruned — re-share
bumps m_ecGen via SetFilePath / Init so any resurrected ECID
naturally takes the full-detail branch again.

The amulegui guards from amule-project#810 and amule-project#819 stay as defensive belt-and-
suspenders for amulegui talking to unpatched / older daemons.
got3nks added a commit to got3nks/amule that referenced this pull request Jun 5, 2026
…_FILES / GET_DLOAD_QUEUE

The EC skip-unchanged opt-in (93a0676 "EC skip-unchanged (4/5)")
gates the per-file emit on `m_ecGen <= ec_threshold` in three
handlers. For unchanged files the server either emits a childless
alive-marker tag (legacy clients) or skips silently (partial-update
clients). Both shortcuts assume the client has previously received
the ECID with full detail. If it hasn't, the alive marker
constructs a ghost CKnownFile from an empty tag (amule-project#810 surface) and
the silent skip leaves the file invisible. The CValueMap-driven
identity suppression on subsequent emissions extends the surface to
INC_UPDATE tags that have children but no identifying fields (amule-project#819
surface).

The amulegui-side guards in amule-project#810 and amule-project#819 cover that client
specifically. Other legacy EC consumers — amuleweb, amulecmd, and
third-party clients — have no analogous guard and silently lose
newly-shared files until restart.

Fix at the source: track per-connection, per-handler ECIDs that
have been sent with full detail. Gate the alive-marker / silent-
skip shortcut on membership in that set. Files the client hasn't
seen fall through to full-detail emission unconditionally, and the
emission populates the per-connection CObjTagMap (so subsequent
INC_UPDATE diffs work) and inserts into the new sent-with-detail
set.

Three handlers, three sets — one per request path because each
handler has its own `m_lastEcGenSeen*` cadence.

Memory cost: bounded by alive-file ECID count per connection
(~360 KB at 91k files; insignificant). Never pruned — re-share
bumps m_ecGen via SetFilePath / Init so any resurrected ECID
naturally takes the full-detail branch again.

The amulegui guards from amule-project#810 and amule-project#819 stay as defensive belt-and-
suspenders for amulegui talking to unpatched / older daemons.
mrjimenez pushed a commit that referenced this pull request Jun 5, 2026
…_FILES / GET_DLOAD_QUEUE

The EC skip-unchanged opt-in (93a0676 "EC skip-unchanged (4/5)")
gates the per-file emit on `m_ecGen <= ec_threshold` in three
handlers. For unchanged files the server either emits a childless
alive-marker tag (legacy clients) or skips silently (partial-update
clients). Both shortcuts assume the client has previously received
the ECID with full detail. If it hasn't, the alive marker
constructs a ghost CKnownFile from an empty tag (#810 surface) and
the silent skip leaves the file invisible. The CValueMap-driven
identity suppression on subsequent emissions extends the surface to
INC_UPDATE tags that have children but no identifying fields (#819
surface).

The amulegui-side guards in #810 and #819 cover that client
specifically. Other legacy EC consumers — amuleweb, amulecmd, and
third-party clients — have no analogous guard and silently lose
newly-shared files until restart.

Fix at the source: track per-connection, per-handler ECIDs that
have been sent with full detail. Gate the alive-marker / silent-
skip shortcut on membership in that set. Files the client hasn't
seen fall through to full-detail emission unconditionally, and the
emission populates the per-connection CObjTagMap (so subsequent
INC_UPDATE diffs work) and inserts into the new sent-with-detail
set.

Three handlers, three sets — one per request path because each
handler has its own `m_lastEcGenSeen*` cadence.

Memory cost: bounded by alive-file ECID count per connection
(~360 KB at 91k files; insignificant). Never pruned — re-share
bumps m_ecGen via SetFilePath / Init so any resurrected ECID
naturally takes the full-detail branch again.

The amulegui guards from #810 and #819 stay as defensive belt-and-
suspenders for amulegui talking to unpatched / older daemons.
mrjimenez pushed a commit to mrjimenez/amule that referenced this pull request Aug 8, 2026
…ject#819)

amule-project#818 moved the x64 packaging leg to CLANG64 but left build.sh's MSYSTEM
whitelist at CLANGARM64/MINGW64, so every x64 packaging run now dies with
"fatal: unsupported WINDOWS_MSYSTEM=CLANG64" before configuring anything.

Map CLANG64 to the x64 arch suffix alongside MINGW64, which stays accepted
for local builds -- capped at wx 3.2 and therefore without system dark
mode, now noted in versions.env.

The installer jobs are unaffected: their x64 leg is still MINGW64, which
maps to the same x64 suffix and so still matches the windows-x64 artifact.

Missed in amule-project#818 because the workflow change was reviewed against
packaging.yml alone; the value is consumed by a script the diff never
touched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants