Skip to content

Conversation

dr-orlovsky
Copy link
Member

@dr-orlovsky dr-orlovsky commented May 11, 2025

This PR by Bitfinex team summarizes their 4-month work on making v0.11 as simple as possible, including taking many ideas from v0.12 (seal unification, monimorphisation of contracts over specific underlying chain; state unification, removal of Pedersen commitments etc)

dr-orlovsky and others added 30 commits September 18, 2024 10:25
testnet may have blocks which timestamps are not aligned with their heights
fmt keeps changing all the time. Now they introduced new "editions" feature, which by default does a lot of changes to the codebase by mingling with alphabetical sorting of all imports, doing them in case-insentive way. This PR allows to avoid that dramatic changes
due to rustfix dependency
@dr-orlovsky dr-orlovsky mentioned this pull request May 11, 2025
@dr-orlovsky dr-orlovsky changed the title Refactoring of v0.11 into v0.11.1 Refactoring v0.11 into v0.11.1 in style of v0.12 simplifications May 11, 2025
@dr-orlovsky dr-orlovsky changed the base branch from v0.11 to master May 11, 2025 14:10
Copy link

codecov bot commented May 11, 2025

Codecov Report

Attention: Patch coverage is 10.51095% with 613 lines in your changes missing coverage. Please review.

Project coverage is 9.8%. Comparing base (7ae9760) to head (bbc63f8).
Report is 137 commits behind head on master.

Files with missing lines Patch % Lines
src/validation/validator.rs 0.0% 137 Missing ⚠️
src/schema/schema.rs 0.0% 88 Missing ⚠️
src/validation/logic.rs 0.0% 76 Missing ⚠️
src/vm/op_contract.rs 0.0% 75 Missing ⚠️
src/operation/assignments.rs 0.0% 69 Missing ⚠️
src/operation/layer1.rs 0.0% 37 Missing ⚠️
src/vm/contract.rs 52.6% 37 Missing ⚠️
src/operation/bundle.rs 6.5% 29 Missing ⚠️
src/validation/schema.rs 0.0% 16 Missing ⚠️
src/operation/operations.rs 0.0% 11 Missing ⚠️
... and 11 more

❌ Your patch check has failed because the patch coverage (10.5%) is below the target coverage (60.0%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #288     +/-   ##
=======================================
- Coverage    13.2%   9.8%   -3.4%     
=======================================
  Files          29     27      -2     
  Lines        3883   2670   -1213     
=======================================
- Hits          513    262    -251     
+ Misses       3370   2408    -962     
Flag Coverage Δ
rust 9.8% <10.5%> (-3.4%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member Author

@dr-orlovsky dr-orlovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NACK: this introduces at least one double-spent and one backdoor into the consensus level.

Haven't reviewed other issues; but briefly counted several dozen of them.

chain_net: ChainNet,
context: S::Context<'_>,
safe_height: Option<NonZeroU32>,
trusted_op_seals: BTreeSet<OpId>,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a backdoor into the RGB consensus.

This method is called only externally, exposing an access to the consensus verification for the application level - which is used on top to hide the double-spent issue also introduced in the consensus (see my next comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. trusted_op_seals has nothing to do with the double-spend issue on the modified input map you are claiming
  2. It's not a backdoor. If a wallet is compromised, it may ignore the consignment validation result or avoid running validation altogether. Allowing it to specify a set of opids it considers to be trusted (maybe because it validated them already, or for whatever reason) changes nothing in the security model
  3. It's currently used to handle replace transitions in IFA assets: a wallet may flag the transition as trusted because it involves the replace right of a issuer's delegate. This way, we can strip the history before the replace operation from consignment data. If you know of other ways to provide the same feature we can discuss the removal of trusted_op_seals
    • A wallet still has the ability to not trust the issuer if the history behind replace operations gets published somewhere, by reconstructing the complete consignment and validating with an empty set of trusted seals
    • It might also be useful for wallets to implement a sort of cache: store the opids of transitions that were validated so that their validation can be skipped if they appear in the history of multiple incoming transfers. This cache is not a killer feature though, if it ends up being the only reason why we have trusted_op_seals I'm ok with dropping it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not me who invented separation of concerns - or a difference of consensus from non-consensus things.

This change clearly breaks both of matters. For zero reason. Not acceptable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For zero reason

I explained the reason. Until we have an alternative solution or we find issues/attacks I tend to be against dropping it

serde(crate = "serde_crate", transparent)
)]
pub struct InputMap(Confined<BTreeMap<Vin, OpId>, 1, U16MAX>);
pub struct InputOpids(NonEmptyOrdSet<OpId, U16MAX>);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduce a double-spending issue into the consensus, and doesn't make any sense.

  • if you require all transitions to be present, there is no need for the TransitionBundle at all: it adds nothing. Also, you kill the multi-party transaction use case privacy: payjoins, coinjoins, Ark etc - and will need a new structure next to PSBT and a more complex interactive process to get RGB working there

  • as of now, you do not require in cosensus for all transactions presence, thus, you have a double-spent attack in v0.11.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation code makes sure the double spend is not possible. This change allows to move different allocation types on a single UTXO, each with their transition.

you kill the multi-party transaction use case privacy

We have some work going on to re-introduce that feature.

you do not require in cosensus for all transactions presence

This is not true, we also did a test to prove that https://github.com/St333p/rgb-tests/blob/24ee570715c7e18d5ede7aa5ed38fa305c2b0086/tests/transfers.rs#L2258

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation code makes TranstionBundle redundant and not used, introducing additional complexity and attack vector, hidden by other parts of the code (which may change in the future, and this will be forgotten).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TransitionBundle is still useful, there are cases in which one needs to bundle transitions of the same contract (e.g. allocations of different types on a single UTXO). Also, the ability to omit transitions from the bundle can be brought back safely by changing the input_map structure to Map<Opout, OpId>, we're currently working on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TransitionBundle is still useful, there are cases in which one needs to bundle transitions of the same contract (e.g. allocations of different types on a single UTXO).

No, it is not: #292 (comment)

if self.trusted_op_seals.contains(&opid) {
continue;
}
let Some(outpoints) = input_map.get(&opid) else {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, the known_transitions field of the bundle is not checked at all!

Instead, everything agains double-spent is relied onto a self.trusted_op_seals, injected as a backdoor from the application level!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The double spend is prevented by the following check:

let Opout { op, ty, no } = input;
if !self.input_assignments.borrow_mut().insert(input) {
    self.status
        .borrow_mut()
        .add_failure(Failure::DoubleSpend(input));
}

together with the fact that all transitions in the input_map are effectively required to be in the known_transitions by the check at line 419 (variable input_map is built from bundle's known_transitions).

The self.trusted_op_seals is not there as a protection from double spends. Its purpose is to allow a wallet to skip validation of certain seals. It could be misused, the same as a wallet can run modified RGB libraries to do whatever it wants, but sane wallets will reject the transfer if invalid. For details about that see #288 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls see above

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.

3 participants