From 3d25d3a2067ed0c55749554cc53f4776003a67df Mon Sep 17 00:00:00 2001 From: abishek Date: Fri, 3 Jan 2025 16:21:51 +0545 Subject: [PATCH] l1 batch test fix --- bin/prover-client/src/operators/checkpoint.rs | 18 ++++++- bin/prover-client/src/operators/l1_batch.rs | 47 +++++++++---------- bin/prover-client/src/rpc_server.rs | 2 +- crates/rpc/prover-client-api/src/lib.rs | 2 +- .../fn_prover_l1_batch_dispatch.py | 29 +++++++++--- functional-tests/fn_prover_l1_dispatch.py | 8 +--- functional-tests/utils.py | 5 ++ 7 files changed, 70 insertions(+), 41 deletions(-) diff --git a/bin/prover-client/src/operators/checkpoint.rs b/bin/prover-client/src/operators/checkpoint.rs index 2c199efc5c..a697e1858b 100644 --- a/bin/prover-client/src/operators/checkpoint.rs +++ b/bin/prover-client/src/operators/checkpoint.rs @@ -84,9 +84,25 @@ impl ProvingOp for CheckpointOperator { let ckp_proof_id = ProofContext::Checkpoint(ckp_idx); + // Doing the manual block idx to id transformation. Will be removed once checkpoint_info + // include the range in terms of block_id. + // https://alpenlabs.atlassian.net/browse/STR-756 + let start_l1_block_id = self + .l1_batch_operator + .get_block_at(checkpoint_info.l1_range.0) + .await?; + let end_l1_block_id = self + .l1_batch_operator + .get_block_at(checkpoint_info.l1_range.1) + .await?; + let l1_batch_keys = self .l1_batch_operator - .create_task(checkpoint_info.l1_range, task_tracker.clone(), db) + .create_task( + (start_l1_block_id, end_l1_block_id), + task_tracker.clone(), + db, + ) .await?; let l1_batch_id = l1_batch_keys.first().expect("at least one").context(); diff --git a/bin/prover-client/src/operators/l1_batch.rs b/bin/prover-client/src/operators/l1_batch.rs index 4ca5972db5..b271e652f0 100644 --- a/bin/prover-client/src/operators/l1_batch.rs +++ b/bin/prover-client/src/operators/l1_batch.rs @@ -23,12 +23,9 @@ use crate::{errors::ProvingTaskError, task_tracker::TaskTracker}; /// A struct that implements the [`ProvingOp`] trait for L1 Batch Proof generation. /// -/// It is responsible for managing the data and tasks required to generate proofs for L1 Batch. It +/// It is responsible for managing the data to generate proofs for L1 Batch. It /// fetches the necessary inputs for the [`L1BatchProver`] by: -/// -/// - Utilizing the [`BtcBlockspaceOperator`] to create and manage proving tasks for BTC Blockspace. -/// The resulting BTC Blockspace proofs are incorporated as part of the input for the CL STF -/// proof. +/// - Fetching the Bitcoin blocks and verification state for the given block range. /// - Interfacing with the Bitcoin Client to fetch additional required information for batch proofs. #[derive(Debug, Clone)] pub struct L1BatchOperator { @@ -44,14 +41,6 @@ impl L1BatchOperator { } } - async fn get_block_at(&self, height: u64) -> Result { - self.btc_client - .get_block_at(height) - .await - .inspect_err(|_| error!(%height, "Failed to fetch BTC block")) - .map_err(|e| ProvingTaskError::RpcError(e.to_string())) - } - async fn get_block(&self, block_id: L1BlockId) -> Result { self.btc_client .get_block(&block_id.into()) @@ -61,12 +50,7 @@ impl L1BatchOperator { } async fn get_block_height(&self, block_id: L1BlockId) -> Result { - let block = self - .btc_client - .get_block(&block_id.into()) - .await - .inspect_err(|_| error!(%block_id, "Failed to fetch BTC block")) - .map_err(|e| ProvingTaskError::RpcError(e.to_string()))?; + let block = self.get_block(block_id).await?; let block_height = self .btc_client @@ -79,7 +63,7 @@ impl L1BatchOperator { } /// Retrieves the specified number of ancestor block IDs for the given block ID. - pub async fn get_block_ancestors( + async fn get_block_ancestors( &self, block_id: L1BlockId, n_ancestors: u64, @@ -94,22 +78,33 @@ impl L1BatchOperator { Ok(ancestors) } + + /// Retrieves the block ID at the specified height. + /// + /// Note: This function will be removed once checkpoint_info includes the block ID range. + /// Currently, it requires a manual L1 block index-to-ID conversion by the checkpoint operator. + // https://alpenlabs.atlassian.net/browse/STR-756 + pub async fn get_block_at(&self, height: u64) -> Result { + let block_hash = self + .btc_client + .get_block_hash(height) + .await + .map_err(|e| ProvingTaskError::RpcError(e.to_string()))?; + Ok(block_hash.into()) + } } impl ProvingOp for L1BatchOperator { type Prover = L1BatchProver; - type Params = (u64, u64); + type Params = (L1BlockId, L1BlockId); async fn create_task( &self, - params: (u64, u64), + params: Self::Params, task_tracker: Arc>, _db: &ProofDb, ) -> Result, ProvingTaskError> { - let (start_height, end_height) = params; - - let start_blkid = self.get_block_at(start_height).await?.block_hash().into(); - let end_blkid = self.get_block_at(end_height).await?.block_hash().into(); + let (start_blkid, end_blkid) = params; let l1_batch_proof_id = ProofContext::L1Batch(start_blkid, end_blkid); let mut task_tracker = task_tracker.lock().await; diff --git a/bin/prover-client/src/rpc_server.rs b/bin/prover-client/src/rpc_server.rs index 32e600ca8c..8027ab3a27 100644 --- a/bin/prover-client/src/rpc_server.rs +++ b/bin/prover-client/src/rpc_server.rs @@ -106,7 +106,7 @@ impl StrataProverClientApiServer for ProverClientRpc { .expect("failed to create task")) } - async fn prove_l1_batch(&self, l1_range: (u64, u64)) -> RpcResult> { + async fn prove_l1_batch(&self, l1_range: (L1BlockId, L1BlockId)) -> RpcResult> { Ok(self .operator .l1_batch_operator() diff --git a/crates/rpc/prover-client-api/src/lib.rs b/crates/rpc/prover-client-api/src/lib.rs index a633d966fc..48e2d99a09 100644 --- a/crates/rpc/prover-client-api/src/lib.rs +++ b/crates/rpc/prover-client-api/src/lib.rs @@ -22,7 +22,7 @@ pub trait StrataProverClientApi { /// Start proving the given l1 Batch #[method(name = "proveL1Batch")] - async fn prove_l1_batch(&self, l1_range: (u64, u64)) -> RpcResult>; + async fn prove_l1_batch(&self, l1_range: (L1BlockId, L1BlockId)) -> RpcResult>; /// Start proving the given l2 batch #[method(name = "proveL2Batch")] diff --git a/functional-tests/fn_prover_l1_batch_dispatch.py b/functional-tests/fn_prover_l1_batch_dispatch.py index 4dfa394849..1c683a5171 100644 --- a/functional-tests/fn_prover_l1_batch_dispatch.py +++ b/functional-tests/fn_prover_l1_batch_dispatch.py @@ -1,9 +1,16 @@ import time import flexitest +from bitcoinlib.services.bitcoind import BitcoindClient import testenv -from utils import wait_for_proof_with_time_out +from utils import wait_for_proof_with_time_out, bytes_to_big_endian + +# Parameters defining the range of L1 blocks to be proven. +L1_PROVER_PARAMS = { + "START_BLOCK_HEIGHT": 1, + "END_BLOCK_HEIGHT": 3, +} @flexitest.register @@ -12,16 +19,26 @@ def __init__(self, ctx: flexitest.InitContext): ctx.set_env("prover") def main(self, ctx: flexitest.RunContext): + btc = ctx.get_service("bitcoin") prover_client = ctx.get_service("prover_client") + + btcrpc: BitcoindClient = btc.create_rpc() prover_client_rpc = prover_client.create_rpc() - # Wait for the some block building + # Allow time for blocks to build time.sleep(5) - task_ids = prover_client_rpc.dev_strata_proveL1Batch((1, 2)) + start_block_hash = bytes_to_big_endian( + btcrpc.proxy.getblockhash(L1_PROVER_PARAMS["START_BLOCK_HEIGHT"]) + ) + end_block_hash = bytes_to_big_endian( + btcrpc.proxy.getblockhash(L1_PROVER_PARAMS["END_BLOCK_HEIGHT"]) + ) + + task_ids = prover_client_rpc.dev_strata_proveL1Batch((start_block_hash, end_block_hash)) task_id = task_ids[0] - self.debug(f"using task id: {task_id}") + self.debug(f"Using task id: {task_id}") assert task_id is not None - time_out = 10 * 60 - wait_for_proof_with_time_out(prover_client_rpc, task_id, time_out=time_out) + proof_timeout_seconds = 10 * 60 + wait_for_proof_with_time_out(prover_client_rpc, task_id, time_out=proof_timeout_seconds) diff --git a/functional-tests/fn_prover_l1_dispatch.py b/functional-tests/fn_prover_l1_dispatch.py index 63a7908630..c9d292d7c5 100644 --- a/functional-tests/fn_prover_l1_dispatch.py +++ b/functional-tests/fn_prover_l1_dispatch.py @@ -4,7 +4,7 @@ from bitcoinlib.services.bitcoind import BitcoindClient import testenv -from utils import wait_for_proof_with_time_out +from utils import wait_for_proof_with_time_out, bytes_to_big_endian @flexitest.register @@ -27,7 +27,7 @@ def main(self, ctx: flexitest.RunContext): blockhash = btcrpc.proxy.getblockhash(block_height) print(block_height, blockhash) - task_ids = prover_client_rpc.dev_strata_proveBtcBlock(fix_reversed_blockhash(blockhash)) + task_ids = prover_client_rpc.dev_strata_proveBtcBlock(bytes_to_big_endian(blockhash)) self.debug(f"got task ids: {task_ids}") task_id = task_ids[0] self.debug(f"using task id: {task_id}") @@ -35,7 +35,3 @@ def main(self, ctx: flexitest.RunContext): time_out = 10 * 60 wait_for_proof_with_time_out(prover_client_rpc, task_id, time_out=time_out) - - -def fix_reversed_blockhash(reversed_hash): - return "".join(reversed([reversed_hash[i : i + 2] for i in range(0, len(reversed_hash), 2)])) diff --git a/functional-tests/utils.py b/functional-tests/utils.py index 56b79435f2..f195caa381 100644 --- a/functional-tests/utils.py +++ b/functional-tests/utils.py @@ -507,3 +507,8 @@ def submit_da_blob(btcrpc: BitcoindClient, seqrpc: JsonrpcClient, blobdata: str) timeout=10, ) return tx + + +def bytes_to_big_endian(hash): + """Reverses the byte order of a hexadecimal string to produce big-endian format.""" + return "".join(reversed([hash[i : i + 2] for i in range(0, len(hash), 2)]))