"I wonder if any of the readers is going to find that scenario (no @small.minion, not you). Identify assumptions, challenge them, see what happens."
The Three-Body Two-Fork problem ;-)
I'm afraid that your small hint for all non-small minions was in fact too big ;-)
Or I might be biased by talking with you too much ;-)
"It keeps track of cashed out comments in local map - just the list of comment ids bound to block number."
...marking it as “ready to archive” once that block becomes irreversible, but in the meantime things can happen. :-)
Identify assumptions
So one assumption is that if fork switch occurs, the upcoming blocks on the new fork will rebuild the correct state. For example, if cashout was undone by a fork, the new fork will either cash out the comment again (adding it back to the map) or delete it (in which case, as noted, the archiver should simply do nothing).
The other is that each comment only enters the "archive process" once per lifetime.
Two quick forks break the expectation that the first fork’s outcome will either archive or rebuild the state cleanly before another fork hits.
Challenge them
- Comment
gtg
reaches its cashout block on this chain1, is added to the archive’s map with its cashout block number. At this point,gtg
is still in comment index, i.e. not yet removed, because the block isn’t irreversible - First fork switch to chain2: before block
gtg
’s cashout becomes irreversible on chain1, the node switches to an alternate chain2, undoing the last blocks of chain1. This fork switch reverts the cashout event forgtg
. In the new reality of chian2, commentgtg
wasn't cashed out (might be still active, chain2 might containgtg
's deletion). But, the archive’s map still containsgtg
from chain1, because that map isn’t reverted on fork undo.
So currently:
- the comment
gtg
is still present in memory (since we never removed it because it wasn’t irreversible on chain1) - the archive map has a stale entry for
gtg
(tied to the block number from chain1's reality)
If chain2 includedgtg
's deletion, the comment object would be removed by normal chain logic, but the archive map would still have an entry for the “archivegtg
when block x (the old fork’s block) is irreversible” which is now irrelevant.
- Second fork switch: In fact this could be switching back to the original chain1 (if it continues) or to yet another chain3. In either case, comment
gtg
’s cashout now happens again on the new fork.
So for example if we reverted to the original chain1, we’d replay the cashout ofgtg
.
When this second fork’s cashout occurs, theon_cashout()
logic will run again for commentgtg
.
This is where the problem can occur. The code needs to handle the fact that comment gtg
is still in the archive’s map from the first cashout event.
See what happens
I prefer not to, at least not on the mainnet ;-)
RE: Comment archive - for node operators and technical