Skip to content

Rename and refactor TxProvingCapability to use correct abstraction #576

@dan-da

Description

@dan-da

There has been a discussion about TxProvingCapability and the fact that as currently implemented it is a bad fit for ProofBuilder and ProverJob which deal solely with Proofs.

This "bad fit" is because TxProvingCapability is presently just an enum with variants for PrimitiveWitness, ProofCollection, and SIngleProof. These variants are tied to transactions proofs, but Proof is a more general and abstract type than that.

So the general idea then is rename TxProvingCapability to just ProvingCapability and make it reflect a machine's actual ability to generate proofs. Concretely by including a field for max_log2_padded_height. Although there may be other factor(s).

Here is where this change is first proposed:
#550 (comment)

note to implementor, maybe me: the convo following above comment has additional suggestions that should be considered/included

The new type might look something like:

pub VmProvingCapability {
  // from CLI, or auto determined.
   max_log2_padded_height: u8,
}

impl VmProvingCapability {
    pub async fn ensure_can_prove_claim_triple(
        &self,
        program: Program,
        claim: Claim,
        nondeterminism: NonDeterminism,
    ) -> bool {
        let mut vmstate = VMState::new(program, claim.input.into(), nondeterminism);
        self.can_prove_claim(&mut vmstate).await
    }

    pub async fn ensure_can_prove_claim(&self, vmstate: &mut VMState) -> bool {
        // note: this would run inside spawn_blocking().
        if vmstate.run().is_ok() {
            let big_max = 2u32.pow(max.into());
            return vmstate.cycle_count.next_power_of_two() < big_max;
        }
        false
    }

    // automatically detect the max_log2_padded_height for this device.
    pub async fn auto_detect() -> Self {
        // how to impl this?
    }

    // the above methods may be all we will need.
    // below methods demonstrate how we could accommodate arbitrary classes of claims/proofs, old or new.
    // and support fast (estimated) checks based on pre-determined log2_padded_height values.
    // note: all integer constants are basically just made up and would need to be determined.

    fn can_prove(&self, log2_padded_height: u8) -> bool {
        self.max_log2_padded_height >= log2_padded_height
    }

    pub fn can_prove_tx_proof(&self, txp: TransactionProofType) -> bool {
        match txp {
            TransactionProofType::SingleProof => self.can_prove_tx_single_proof(),
            TransactionProofType::ProofCollection => self.can_prove_tx_proof_collection(),
            TransactionProofType::PrimitiveWitness => true,
        }
    }

    pub fn can_prove_tx_single_proof(&self) -> bool {
        self.can_prove(22);
    }

    pub fn can_prove_tx_proof_collection(&self) -> bool {
        self.can_prove(11);
    }

    pub fn can_prove_block_proof(&self) -> bool {
        self.can_prove_single_proof();   // not sure if this is right
    }

    pub fn can_prove_kernel_to_outputs(&self) -> bool {
        self.can_prove(10);
    }

    pub fn can_prove_lockscript(&self) -> bool {
        self.can_prove(6);
    }

    pub fn can_prove_typescript(&self) -> bool {
        self.can_prove(5);
    }

    /// and so on with any type.   

    // note that we could get much fancier, eg by using a trait:

    pub fn can_prove_provable_type(&self, provable: &impl ProvableType) -> bool {
        self.can_prove(provable_type.log2_padded_height_estimate());
    }

note: improvements have been suggested in the original thread. the above is just a starting point

An unresolved (not previously asked) question is: how can we auto-detect a machine's max log2_padded_height capability? ie, what does the implementation of the auto_detect() method look like? I think that worst case, we can do something similar to cli_args::Args::proving_capability() which check RAM and CPU capacities and maps those to specific values. But maybe there is a better and more precise approach, eg running some kind of (quick) stress test? @jan-ferdinand I'm hoping you will have some ideas/suggestions here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    architecturechoreHas to be done (and without dopamine)discussionsearch for truth guided by arguments and counter-argumentsenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions