Hi Team, there is another PR I want to push to the rgb-ops, that is, Conceal everything we do not need.
But first, I set up a new issue, so your team can check if it is valid or makes sense.
For what I think that Conceal everything we do not need should do:
- Keep the same set of transitions (needed for validation).
- For each transition’s assignments, convert Assign::Revealed to Assign::ConfidentialSeal unless the seal is explicitly required by the caller (e.g. the outputs the consignment is for).
- This reduces leakage while keeping validation intact because the commitment uses concealed seals.
Is that safe?
- Validation depends on commitments, not revealed seals.
- Concealing seals doesn’t change commitments (only reveals), so the transition IDs(opid) and bundle IDs remain valid.
- Receivers who know their output can still match by secret seal even if the explicit seal is concealed.
So here is what I have done:
- Added concealment of revealed assignment seals not in the requested output set when building consignments
- Threaded outputs through consign_operations and consign_bundles, and updated the fascia path to pass the output slice
The code snippets:
let (mut sorted_bundles, dag) =
self.sort_bundles(bundles, contract_id, build_opouts_dag, &genesis)?;
let keep_output_seals = outputs.iter().copied().collect::<HashSet<_>>();
for witness_bundle in &mut sorted_bundles {
for KnownTransition { transition, .. } in
witness_bundle.bundle_mut().known_transitions.iter_mut()
{
for typed_assigns in transition.assignments.values_mut() {
Self::conceal_unneeded_assigns(typed_assigns, &keep_output_seals);
}
}
}
// callback after sort bundles
fn conceal_unneeded_assigns(
typed_assigns: &mut TypedAssigns<GraphSeal>,
keep_output_seals: &HashSet<OutputSeal>,
) {
match typed_assigns {
TypedAssigns::Declarative(assigns) => {
for assign in assigns.iter_mut() {
let Assign::Revealed { seal, .. } = assign else {
continue;
};
let keep_revealed = seal
.to_output_seal()
.map(|output| keep_output_seals.contains(&output))
.unwrap_or(false);
if !keep_revealed {
*assign = assign.conceal();
}
}
}
TypedAssigns::Fungible(assigns) => {
for assign in assigns.iter_mut() {
let Assign::Revealed { seal, .. } = assign else {
continue;
};
let keep_revealed = seal
.to_output_seal()
.map(|output| keep_output_seals.contains(&output))
.unwrap_or(false);
if !keep_revealed {
*assign = assign.conceal();
}
}
}
TypedAssigns::Structured(assigns) => {
for assign in assigns.iter_mut() {
let Assign::Revealed { seal, .. } = assign else {
continue;
};
let keep_revealed = seal
.to_output_seal()
.map(|output| keep_output_seals.contains(&output))
.unwrap_or(false);
if !keep_revealed {
*assign = assign.conceal();
}
}
}
}
}
Hi Team, there is another PR I want to push to the rgb-ops, that is,
Conceal everything we do not need.But first, I set up a new issue, so your team can check if it is valid or makes sense.
For what I think that
Conceal everything we do not needshould do:Is that safe?
So here is what I have done:
The code snippets: