Only increment current_version_id when an update is applied - #337
Conversation
a7a53d5 to
ef0fb82
Compare
Duplicate updates routed to Confirm Duplicate Update never append to update_hash_history, so bumping the counter for every tuple pushed current_version_id ahead of the history. That inflated the returned versionId and made a valid history like [v2, v2-again, v3] fail with a false LATE_PUBLISHING. Move the increment out of the Process updates loop and into Apply update, keeping the invariant current_version_id == update_hash_history.length + 1.
The construction-time MUST on targetVersionId does not protect a resolver handed a non-conforming update: targetVersionId of 1, 0, or negative routes into update_hash_history[targetVersionId - 2] with a negative index, and behavior from there is language-defined. Require targetVersionId >= 2 before the access and raise INVALID_DID_UPDATE otherwise, so all resolvers reject malformed updates the same way.
ef0fb82 to
f75f7ac
Compare
Drop "Increment `current_version_id`." onto a newline Co-authored-by: Dan Pape <dpape@dpape.com>
|
I'm confused. "Confirm Duplicate Update" confirms a duplicate by raising an error. When the error is raised, processing the I agree with the new "if |
|
"Confirm Duplicate Update" only raises when the hashes differ.
Issue #321 and this corresponding PR are primarily focused on the case of when hashes match because then the "Confirm Duplicate Update" sub-routine returns successfully and continues executing the outer loop, which would then execute the step "Increment The whole point of the "Confirm Duplicate Update" step is to allow users the ability to make the mistake of broadcasting an identical update more than once without bricking their DID resolution on a "LATE PUBLISHING" error, since technically its not late publishing. The net side effect of how we wrote it, however, is that it will end up inflating |
There was a problem hiding this comment.
That's what I'm missing. I've misread my own code! An increment happens in that location, but the result is stored in a separate variable and used for the condition on next line. This error was probably introduced by me when translating this code to the new spec prose. A misfortunate simplification.
Yes, the increment to current_version_id needs to be moved into "Apply update". That is a much closer match to the code that this description was based on.
I went through a whole comparison between the code and the old spec it was based on. That revealed a gap in the old spec that I believe the new spec with this PR adequately resolves. It doesn't matter for this PR, so I'll hide the analysis below. It might be useful to future archeologists.
Analysis of old spec...
The code I'm looking at was based on the pandoc version of the spec: https://github.com/dcdpr/did-btcr2/blob/75ae6934458922e70d24d8f3c22db423c7df017f/chapters/CRUD-Operations.md#traverse-bitcoin-blockchain-history.
Step 10 (you'll have to scroll down a page) is the process in question. Step 10.i is update.targetVersionId <= current_version_id, 10.ii is update.targetVersionId == current_version_id + 1, and 10.iii is NOT update.targetVersionId > current_version_id + 1, it is ... + 2! current_version_id gets incremented within the == case.
The way this older spec (and the code that I'm comparing to) was written, the third condition requires the extra increment, and that leaves a gap where update.targetVersionId > current_version_id + 1 is not actually checked. (In short, the old spec and the code are missing else clauses on the latter two conditions. The new spec fixes this ambiguity by stating "Only one of three possible conditions will occur:")
I do believe we need to check that gap (unlike the old spec). And I think that moving the increment into "Apply update" is the right thing to do (matching the old spec).
Moves the
current_version_idincrement out of the "Process updates Array" loop and into "Apply update", so duplicates confirmed via "Confirm Duplicate Update" no longer advance the counter. This keepscurrent_version_idin lockstep withupdate_hash_history(fixes the inflatedversionIdand the falseLATE_PUBLISHINGon histories like [v2, v2-again, v3]).Also adds the guard discussed in the issue thread: "Confirm Duplicate Update" now raises
INVALID_DID_UPDATEwhentargetVersionId < 2, so a non-conforming update can't reach the history lookup with a negative index and all resolvers reject it the same way.Fixes #321