Skip to content

fix: Reject duplicate BitName registrations within a single block - #48

Open
giaki3003 wants to merge 1 commit into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260610-2220-rustl2-bitnames-bitassets--bitnames-bitassets-enforce-registration-name-uni
Open

fix: Reject duplicate BitName registrations within a single block#48
giaki3003 wants to merge 1 commit into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260610-2220-rustl2-bitnames-bitassets--bitnames-bitassets-enforce-registration-name-uni

Conversation

@giaki3003

Copy link
Copy Markdown
Contributor

What's wrong

State::validate_filled_transaction (lib/state/mod.rs) checks that a registered name is not already taken, but it reads the pre-block DB, so it cannot see a registration earlier in the same block. block::validate / block::prevalidate (lib/state/block.rs) reject double-spent outpoints but do not look at registration name hashes at all.

Two registrations of the same name can therefore both be individually valid — distinct nonces give distinct commitments, so each burns a real reservation — and both connect. The second apply_registration overwrites the canonical bitnames row, and that overwrite is not invertible: on disconnect the second revert_registration deletes the shared row, and the first then fails with Error::Missing. A node that connected such a block can no longer disconnect it, so it is stuck on that branch across a reorg.

The fix

Add a per-block uniqueness check over registration_name_hash() in both validate and prevalidate, right next to the existing double-spend check, returning a new Error::DuplicateBitNameRegistration. As defence in depth, apply_registration now returns BitName::AlreadyRegistered instead of overwriting an existing row. Happy to move the new variant under error::BitName if you prefer it there.

Tests

Adds validate_rejects_duplicate_registration_within_block: two registrations for one name, each asserted to pass validate_filled_transaction, with the containing block asserted to be rejected.

Finding report (access-controlled): https://giaki3003.tech/#/findings/20260610-2220-rustl2-bitnames-bitassets-same-block-duplicate-registration-disconnect-noninvertible


First of a short series of 1 fixes for this repo, based on master. The rest build on this branch and will follow.

…inst the committed pre-block DB (never within the candidate block), so two same-name registrations connect and overwrite the canonical row, and disconnecting that block is non-invertible (the second revert deletes the shared row, the first then fails with Error::Missing), wedging the node on the losing branch during any reorg.

Bug: w3-20260610-2220-rustl2-bitnames-bitassets- (primary)
Finding: findings/20260610-2220-rustl2-bitnames-bitassets-same-block-duplicate-registration-disconnect-noninvertible.md
Severity: R4-T2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 68317bc)
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.

1 participant