Repository navigation
fix(delegation): no depth ceiling for an absent maxDepth, refuse minting without a ceiling - #25
Merged
Merged
Conversation
…maxDepth verify_delegation read an absent maxDepth as 0, so every signed legacy record without the member failed at currentDepth 1 or more. docs/SPEC-v1.1.md section 4.1 says an absent max_depth has no ceiling on verification and v1.1 verifiers enforce the limit when the field is present, and the TypeScript verifyDelegation applies none. Absence now skips the comparison. A present maxDepth is compared as before, including present values that are not numbers, which are still not compared. Writers are unchanged and still emit maxDepth 1 when the caller omits it. Regression: the vendored TypeScript case delegation-without-max-depth-at-depth-64 and a locally signed record at currentDepth 3 fail before this change. Explicit limits are pinned as controls. Signed-off-by: Tymofii Pidlisnyi <tima@aeoess.com>
…epth Separate from the verification change before it. Accepting a signed record without maxDepth on verification is not permission to mint a child under it: with no ceiling on the parent there is no signed value for the child to inherit. sub_delegate raised KeyError on an absent maxDepth and TypeError on a non-numeric one. It now raises ValueError naming the missing ceiling. Parents with an explicit maxDepth are unchanged. Signed-off-by: Tymofii Pidlisnyi <tima@aeoess.com>
… depths to mint The canonical form drops None members, so "maxDepth": None signs to the same bytes as an absent member. A paired test pins that both get the same verdict. sub_delegate now requires a non-negative integer maxDepth and currentDepth on the parent, as the TypeScript subDelegate does. Signed-off-by: Tymofii Pidlisnyi <tima@aeoess.com>
…unsafe ones 2.0 and 0.0 canonicalize to the same signed bytes as 2 and 0, and the TypeScript subDelegate accepts them, but the integer guard refused them here. The guard now accepts finite integer-valued numbers and refuses booleans, fractions, negatives and values beyond 2**53 - 1, which the TypeScript SDK cannot represent exactly. Tests for both sides and for currentDepth. Signed-off-by: Tymofii Pidlisnyi <tima@aeoess.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem this solves
verify_delegationread an absentmaxDepthas 0, so every signed legacy record without the member failed atcurrentDepth1 or more, while a present"maxDepth": Noneskipped the check. The canonical form drops None members, so those two forms sign to the same bytes, and a holder could add the None member to turn an invalid record valid without the key.sub_delegateraisedKeyErroron a parent withoutmaxDepthandTypeErroron a non-numeric one.Why this change was made
docs/SPEC-v1.1.mdsection 4.1 says an absentmax_depthhas no ceiling on verification, and the TypeScriptverifyDelegationapplies none. Reading 0 matched neither. Verification has to give both signed-identical forms one verdict, and minting under a parent with no ceiling is refused, as in the TypeScript SDK.User impact
maxDepthat depth 1 or more, whichverify_delegationrejected, now verify. A present numericmaxDepthis compared as before. A present value that is not a number is still not compared.sub_delegateraisesValueErrorwhen the parent'smaxDepthorcurrentDepthis not a non-negative integer value. Integer-valued floats such as2.0are accepted, because they sign to the same bytes as2and the TypeScript SDK accepts them. Booleans, fractions, negatives and values beyond 2**53 - 1 are refused.policy.py) still reads an absentmaxDepthas 1. It is a separate acceptance policy and is not changed here, so a record can passverify_delegationand fail F-005.Evidence
tests/test_legacy_maxdepth_absent.py, 11 tests, including the vendored TypeScript vectordelegation-without-max-depth-at-depth-64and a paired None and absent test with equal canonical bytes. The verification, refusal and integer-valued tests fail before the change.pytest: 2750 passed, 6 skipped.Boundaries
maxDepthas malformed is not in this PR. Tracked separately.