Skip to content

Feature/light drp clean#286

Draft
crivasr wants to merge 23 commits intodevfrom
feature/light-drp-clean
Draft

Feature/light drp clean#286
crivasr wants to merge 23 commits intodevfrom
feature/light-drp-clean

Conversation

@crivasr
Copy link
Contributor

@crivasr crivasr commented Mar 17, 2026

No description provided.

futures-util = "0.3"
bitcoind = { git = "https://github.com/FairgateLabs/rust-bitcoind.git", tag = "v0.5.1" }
reqwest = "0.12.23"
garbled_nova = { path = "../rust-bitvmx-gc", features = ["memory"] }
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to remove this until we open rust-bitvmx-gc

Comment on lines +13 to +22
use garbled_nova::gadgets::bigint::alloc_bigint_input;
use garbled_nova::gadgets::bn254::{fq_to_input_bits, Fp254Impl, Fq};
use garbled_nova::digests::recompute_public_digests;
use garbled_nova::garble::GarbledGate;
use garbled_nova::garble::{circuit_loader::load_circuit_from_file, Circuit, CircuitTrait};
use garbled_nova::nova::{
digest_lamport_from_commitments, hex_to_scalar as nova_hex_to_scalar, scalar_to_hex,
Sha256Commitment,
};
use garbled_nova::poseidon_constants;
Copy link
Contributor

Choose a reason for hiding this comment

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

modify this tests so it does not include garbled_nova

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we moved into tests instead of examples. Remove log, macros, light-drp and run.sh

Comment on lines 442 to +484
@@ -469,7 +481,7 @@ fn run_zkp(network: Network, rx: Receiver<()>, tx: Sender<usize>) -> Result<()>
let storage_path = format!("/tmp/zkp_storage_{i}.db");
clear_db(&storage_path);
let prover_dispatcher =
DispatcherHandler::<ProverJobType>::new_with_path(channel, &storage_path, None, true)?;
DispatcherHandler::<ProverJobType>::new_with_path(channel, &storage_path)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

merge dev into this branch again, job_dispatcher interface changed

pub mod cardinal;
pub mod claim;
pub mod dispute;
pub mod light_drp;
Copy link
Contributor

Choose a reason for hiding this comment

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

rename light_drp to gc_drp

Comment on lines 264 to 271
let prover_dispatcher = bitvmx_job_dispatcher::DispatcherHandler::<EmulatorJobType>::new(
emulator_channels[0].clone(),
instances[0].get_store(),
None,
true,
)?;
let verifier_dispatcher = bitvmx_job_dispatcher::DispatcherHandler::<EmulatorJobType>::new(
emulator_channels[1].clone(),
instances[1].get_store(),
Copy link
Contributor

Choose a reason for hiding this comment

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

merge dev

table.add(light_drp::VERIFIER_FINAL, Verifier);

table
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Move the constructor to light_drp (gc_drp)

Comment on lines +91 to +136
pub fn new_for_drp(rounds: u8, inputs: Vec<(usize, String)>) -> Result<Self, BitVMXError> {
if rounds == 0 || inputs.is_empty() {
return Err(Self::invalid_inputs(&inputs));
}

let mut table = TxOwnershipTable { txs: vec![] };
table.add(dispute::START_CH, Verifier);

for (index, owner) in &inputs {
let owner = if owner.as_str() == "verifier" {
Verifier
} else {
Prover
};

table.add(&input_tx_name(*index as u32), owner);
}

//requires that the last input is owned by the prover, otherwise the sequence of timeout txs cannot be properly chained
let &(_last_index, last_owner) =
&inputs.last().ok_or_else(|| Self::invalid_inputs(&inputs))?;
if !last_owner.starts_with("prover") {
return Err(Self::invalid_inputs(&inputs));
}

table.add(dispute::PRE_COMMITMENT, Verifier);
table.add(dispute::COMMITMENT, Prover);
table.add(dispute::POST_COMMITMENT, Verifier);
table.add_nary_search("NARY", 1, rounds);
table.add(dispute::EXECUTE, Prover);
table.add(dispute::CHALLENGE, Verifier);
table.add_nary_search("NARY2", 2, rounds);
table.add(dispute::GET_HASHES_AND_STEP, Prover);
table.add(dispute::CHALLENGE_READ, Verifier);
table.add(dispute::VERIFIER_FINAL, Verifier);
Ok(table)
}

fn add_nary_search(&mut self, nary_type: &str, start_round: u8, total_rounds: u8) {
for round in start_round..=total_rounds {
let prover = format!("{}_PROVER_{}", nary_type, round);
let verifier = format!("{}_VERIFIER_{}", nary_type, round);
self.add(&prover, Prover);
self.add(&verifier, Verifier);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Move back to drp

Comment on lines +176 to +177
if name != dispute::START_CH && name != dispute::VERIFIER_FINAL {
Some((timeout_input_tx(name), true))
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that this struct is general, add a new vec to the struct like exceptions: Vec and configure it in the drp construction, and here use that instead of the constants

Comment on lines +433 to +437
pub fn execute_job<T: ProtocolHandler>(
protocol_handler: &T,
program_context: &ProgramContext,
job_type: EmulatorJobType,
) -> Result<(), BitVMXError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe something like this is better and can be reused with garbled dispatcher

pub fn execute_job<J: Serialize>(
    job_id: &str,
    program_context: &ProgramContext,
    job_type: &J,
) -> Result<(), BitVMXError> {

Comment on lines +256 to +415
fn get_claim_name<T: ProtocolHandler + WithClaimGateConfig>(protocol_handler: &T, other: bool) -> String {
let (role, other_role) = match protocol_handler.role() {
ParticipantRole::Prover => (dispute::PROVER_WINS, dispute::VERIFIER_WINS),
ParticipantRole::Verifier => (dispute::VERIFIER_WINS, dispute::PROVER_WINS),
};
if other {
other_role.to_string()
} else {
role.to_string()
}
}

pub fn auto_claim_start<T: ProtocolHandler + WithClaimGateConfig>(
protocol_handler: &T,
name: &str,
vout: Option<u32>,
program_context: &ProgramContext,
ownership_table: &TxOwnershipTable,
) -> Result<(), BitVMXError> {
if vout.is_some() {
return Ok(());
}

if let Some(orig_tx) = get_tx_name_from_timeout(name) {
if ownership_table.is_other_tx(&orig_tx, protocol_handler.role()) {
let claim_name = ClaimGate::tx_start(&get_claim_name(protocol_handler, false));
let tx = protocol_handler.get_signed(program_context, &claim_name, vec![0.into()])?;
let speedup_data =
protocol_handler.get_speedup_data_from_tx(&tx, program_context, None)?;
info!("{claim_name}: {:?}", tx);
dispatch(
program_context,
protocol_handler,
tx,
Some(speedup_data),
None,
)?;
}
}
Ok(())
}

pub fn claim_state_handle<T: ProtocolHandler + WithClaimGateConfig>(
protocol_handler: &T,
tx_id: Txid,
name: &str,
vout: Option<u32>,
tx_status: TransactionStatus,
program_context: &ProgramContext,
current_height: u32,
timelock_blocks: u32,
) -> Result<(), BitVMXError> {
if vout.is_some() {
return Ok(());
}
let my_claim = get_claim_name(protocol_handler, false);
let other_claim = get_claim_name(protocol_handler, true);
// start claim
if name == ClaimGate::tx_start(dispute::PROVER_WINS) || name == ClaimGate::tx_start(dispute::VERIFIER_WINS) {
// my start
if name == ClaimGate::tx_start(&my_claim) {
info!("{my_claim} SUCCESS dispatch");

let tx = protocol_handler.get_signed(
program_context,
&ClaimGate::tx_success(&my_claim),
vec![1.into()],
)?;
let speedup_data =
protocol_handler.get_speedup_data_from_tx(&tx, program_context, None)?;
let height = Some(current_height + timelock_blocks);
dispatch(
program_context,
protocol_handler,
tx,
Some(speedup_data),
height,
)?;
}
//other start
else {
info!("{other_claim} STOP dispatch attempt");
let tx = protocol_handler.get_signed(
program_context,
&ClaimGate::tx_stop(&other_claim, 0),
vec![0.into()],
)?;
let speedup_data =
protocol_handler.get_speedup_data_from_tx(&tx, program_context, None)?;
dispatch(
program_context,
protocol_handler,
tx,
Some(speedup_data),
None,
)?;
}
}

if (name == ClaimGate::tx_success(dispute::PROVER_WINS)
&& protocol_handler.role() == ParticipantRole::Prover)
|| (name == ClaimGate::tx_success(dispute::VERIFIER_WINS)
&& protocol_handler.role() == ParticipantRole::Verifier)
{
let config =
T::Config::load(&protocol_handler.context().id, &program_context.globals)?;
let actions = match protocol_handler.role() {
ParticipantRole::Prover => &config.get_prover_actions(),
ParticipantRole::Verifier => &config.get_verifier_actions(),
};

for (i, action) in actions.iter().enumerate() {
info!("{}. Execute Action {}", protocol_handler.role(), i);
let tx = protocol_handler.get_signed(
program_context,
&action_wins(&protocol_handler.role(), 1),
vec![0.into(), (action.1[0] as u32).into()],
)?;
let speedup_data =
protocol_handler.get_speedup_data_from_tx(&tx, program_context, None)?;

dispatch(
program_context,
protocol_handler,
tx,
Some(speedup_data),
None,
)?;
}
}

if name.starts_with(&action_wins_prefix(&ParticipantRole::Prover))
|| name.starts_with(&action_wins_prefix(&ParticipantRole::Verifier))
{
let config =
T::Config::load(&protocol_handler.context().id, &program_context.globals)?;

for (protocol_name, protocol_id) in config.get_notify_protocol() {
let protocol = protocol_handler.load_protocol_by_name(&protocol_name, *protocol_id)?;
info!(
"Notifying protocol {} about tx {}:{:?} seen on-chain",
protocol_name, tx_id, vout
);
protocol.notify_external_news(
tx_id,
vout,
tx_status.clone(),
Context::Protocol(protocol_handler.context().id, T::PROGRAM_TYPE.to_string())
.to_string()?,
program_context,
)?;
info!(
"Notified protocol {} about tx {}:{:?} seen on-chain",
protocol_name, tx_id, vout
);
}
}

Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this can be moved to claimgate

Comment on lines +353 to +355
} else {
error!("No Lamport signature found for key: {}", key.name());
return Err(BitVMXError::KeysNotFound(self.context().id));
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be interesting to add the same behavior as in the winternitz function where the key is obtained from the witness. This is helpfull in case where the counter party needs to put the ots in a follow up txs (co-siging and challenge cases)

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