Skip to content

Commit b7078bd

Browse files
authored
Prover Client Functional Tests (#441)
* feat: prover client functional test * tests: deposit & withdrwal functional test * credential check off on the cl guest code * functional tests refactor
1 parent cb20bb4 commit b7078bd

File tree

10 files changed

+347
-31
lines changed

10 files changed

+347
-31
lines changed

bin/prover-client/src/args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub struct Args {
5353
#[argh(
5454
option,
5555
description = "enable prover client checkpoint runner",
56-
default = "true"
56+
default = "false"
5757
)]
5858
pub enable_checkpoint_runner: bool,
5959
}

bin/prover-client/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Number of prover workers to spawn
22
pub const NUM_PROVER_WORKERS: usize = 64;
3+
pub const MAX_PARALLEL_PROVING_INSTANCES: usize = 25;
34

45
// Wait time in seconds for the prover manager loop
56
pub const PROVER_MANAGER_INTERVAL: u64 = 2;

bin/prover-client/src/manager.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ where
5151
.await;
5252

5353
for task in pending_tasks {
54+
if !self.prover.is_available() {
55+
info!("Prover manager occupied skipping this turn..");
56+
break;
57+
}
5458
self.prover.submit_witness(task.id, task.prover_input);
5559
if self.prover.start_proving(task.id).is_err() {
5660
self.task_tracker

bin/prover-client/src/prover.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::elf::{
2626
GUEST_EVM_EE_STF_ELF, GUEST_L1_BATCH_ELF,
2727
};
2828
use crate::{
29-
config::NUM_PROVER_WORKERS,
29+
config::{MAX_PARALLEL_PROVING_INSTANCES, NUM_PROVER_WORKERS},
3030
db::open_rocksdb_database,
3131
primitives::{
3232
prover_input::{ProofWithVkey, ZKVMInput},
@@ -309,6 +309,16 @@ where
309309
}
310310
}
311311

312+
pub(crate) fn is_available(&self) -> bool {
313+
let prover_state = self
314+
.prover_state
315+
.read()
316+
.expect("Failed to acquire write lock");
317+
let num_jobs = prover_state.pending_tasks_count;
318+
319+
num_jobs < MAX_PARALLEL_PROVING_INSTANCES
320+
}
321+
312322
fn save_proof_to_db(&self, task_id: Uuid, proof: &Proof) -> Result<(), anyhow::Error> {
313323
self.db
314324
.prover_store()

bin/strata-reth/res/alpen-dev-chain.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
1717
"config": {
1818
"ethash": {},
19-
"chainId": 12345,
19+
"chainId": 8091,
2020
"homesteadBlock": 0,
2121
"eip150Block": 0,
2222
"eip155Block": 0,

crates/proof-impl/cl-stf/src/lib.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use strata_primitives::{
1010
use strata_proofimpl_evm_ee_stf::ELProofPublicParams;
1111
use strata_state::{
1212
block::ExecSegment,
13-
block_validation::{check_block_credential, validate_block_segments},
13+
block_validation::validate_block_segments,
1414
bridge_ops,
1515
exec_update::{ELDepositData, ExecUpdate, Op, UpdateInput, UpdateOutput},
1616
};
@@ -23,24 +23,14 @@ pub fn verify_and_transition(
2323
el_proof_pp: ELProofPublicParams,
2424
rollup_params: &RollupParams,
2525
) -> (ChainState, Vec<ELDepositData>) {
26-
let deposit_datas = verify_l2_block(&new_l2_block, &el_proof_pp, rollup_params);
26+
let deposit_datas = verify_l2_block(&new_l2_block, &el_proof_pp);
2727
let new_state = apply_state_transition(prev_chstate, &new_l2_block, rollup_params);
2828

2929
(new_state, deposit_datas)
3030
}
3131

3232
/// Verifies the L2 block.
33-
fn verify_l2_block(
34-
block: &L2Block,
35-
el_proof_pp: &ELProofPublicParams,
36-
chain_params: &RollupParams,
37-
) -> Vec<ELDepositData> {
38-
// Assert that the block has been signed by the designated signer
39-
assert!(
40-
check_block_credential(block.header(), &chain_params.cred_rule),
41-
"Block credential verification failed"
42-
);
43-
33+
fn verify_l2_block(block: &L2Block, el_proof_pp: &ELProofPublicParams) -> Vec<ELDepositData> {
4434
// Assert that the block body and header are consistent
4535
assert!(
4636
validate_block_segments(block),

functional-tests/constants.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,5 @@
7474
},
7575
}
7676

77-
PROVER_ROLLUP_PARAMS = {
78-
**DEFAULT_ROLLUP_PARAMS,
79-
"proof_publish_mode": "strict",
80-
"genesis_l1_height": 500,
81-
"cred_rule": "unchecked",
82-
"operator_config": {
83-
"static": [
84-
{
85-
"signing_pk": "1ea7f6c7a924a1e722c09301a826cfd95b21b23a294cec5da3c0b5908e62e0c7",
86-
"wallet_pk": "1ea7f6c7a924a1e722c09301a826cfd95b21b23a294cec5da3c0b5908e62e0c7",
87-
}
88-
]
89-
},
90-
}
77+
78+
PROVER_ROLLUP_PARAMS = {**ROLLUP_PARAMS_FOR_DEPOSIT_TX}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import time
2+
3+
import flexitest
4+
from bitcoinlib.services.bitcoind import BitcoindClient
5+
6+
from constants import (
7+
ROLLUP_PARAMS_FOR_DEPOSIT_TX,
8+
SEQ_PUBLISH_BATCH_INTERVAL_SECS,
9+
)
10+
from utils import wait_for_proof_with_time_out, wait_until
11+
12+
EVM_WAIT_TIME = 2
13+
SATS_TO_WEI = 10**10
14+
15+
withdrawal_intent_event_abi = {
16+
"anonymous": False,
17+
"inputs": [
18+
{"indexed": False, "internalType": "uint64", "name": "amount", "type": "uint64"},
19+
{"indexed": False, "internalType": "bytes", "name": "dest_pk", "type": "bytes32"},
20+
],
21+
"name": "WithdrawalIntentEvent",
22+
"type": "event",
23+
}
24+
event_signature_text = "WithdrawalIntentEvent(uint64,bytes32)"
25+
26+
27+
@flexitest.register
28+
class BridgeDepositTest(flexitest.Test):
29+
def __init__(self, ctx: flexitest.InitContext):
30+
ctx.set_env("prover")
31+
32+
def main(self, ctx: flexitest.RunContext):
33+
evm_addr = "deedf001900dca3ebeefdeadf001900dca3ebeef"
34+
35+
btc = ctx.get_service("bitcoin")
36+
btcrpc: BitcoindClient = btc.create_rpc()
37+
38+
# Do deposit and collect the L1 and L2 where the deposit transaction was included
39+
l2_block_num, l1_deposit_txn_id = self.do_deposit(ctx, evm_addr)
40+
l1_deposit_txn_block_info = btcrpc.proxy.gettransaction(l1_deposit_txn_id)
41+
deposit_txn_block_num = l1_deposit_txn_block_info["blockheight"]
42+
43+
# Init the prover client
44+
prover_client = ctx.get_service("prover_client")
45+
prover_client_rpc = prover_client.create_rpc()
46+
time.sleep(60)
47+
48+
# Dispatch the prover task
49+
# Proving task with with few L1 and L2 blocks including the deposit transaction
50+
l1_range = (deposit_txn_block_num - 1, deposit_txn_block_num + 1)
51+
l2_range = (l2_block_num - 1, l2_block_num + 1)
52+
task_id = prover_client_rpc.dev_strata_proveCheckpointRaw(0, l1_range, l2_range)
53+
print("got proving task_id ", task_id)
54+
assert task_id is not None
55+
56+
time_out = 30 * 60
57+
wait_for_proof_with_time_out(prover_client_rpc, task_id, time_out=time_out)
58+
59+
def do_deposit(self, ctx: flexitest.RunContext, evm_addr: str):
60+
btc = ctx.get_service("bitcoin")
61+
seq = ctx.get_service("sequencer")
62+
63+
seqrpc = seq.create_rpc()
64+
btcrpc: BitcoindClient = btc.create_rpc()
65+
66+
amount_to_send = ROLLUP_PARAMS_FOR_DEPOSIT_TX["deposit_amount"] / 10**8
67+
name = ROLLUP_PARAMS_FOR_DEPOSIT_TX["rollup_name"].encode("utf-8").hex()
68+
69+
addr = "bcrt1pzupt5e8eqvt995r57jmmylxlswqfddsscrrq7njygrkhej3e7q2qur0c76"
70+
outputs = [{addr: amount_to_send}, {"data": f"{name}{evm_addr}"}]
71+
72+
options = {"changePosition": 2}
73+
74+
psbt_result = btcrpc.proxy.walletcreatefundedpsbt([], outputs, 0, options)
75+
psbt = psbt_result["psbt"]
76+
77+
signed_psbt = btcrpc.proxy.walletprocesspsbt(psbt)
78+
79+
finalized_psbt = btcrpc.proxy.finalizepsbt(signed_psbt["psbt"])
80+
deposit_tx = finalized_psbt["hex"]
81+
82+
original_num_deposits = len(seqrpc.strata_getCurrentDeposits())
83+
print(f"Original deposit count: {original_num_deposits}")
84+
85+
reth = ctx.get_service("reth")
86+
rethrpc = reth.create_rpc()
87+
88+
original_balance = int(rethrpc.eth_getBalance(f"0x{evm_addr}"), 16)
89+
print(f"Balance before deposit: {original_balance}")
90+
91+
btc_txn_id = btcrpc.sendrawtransaction(deposit_tx)["txid"]
92+
93+
# check if we are getting deposits
94+
wait_until(
95+
lambda: len(seqrpc.strata_getCurrentDeposits()) > original_num_deposits,
96+
error_with="seem not be getting deposits",
97+
timeout=SEQ_PUBLISH_BATCH_INTERVAL_SECS,
98+
)
99+
100+
current_block_num = int(rethrpc.eth_blockNumber(), base=16)
101+
print(f"Current reth block num: {current_block_num}")
102+
103+
wait_until(
104+
lambda: int(rethrpc.eth_getBalance(f"0x{evm_addr}"), 16) > original_balance,
105+
error_with="eth balance did not update",
106+
timeout=EVM_WAIT_TIME,
107+
)
108+
109+
deposit_amount = ROLLUP_PARAMS_FOR_DEPOSIT_TX["deposit_amount"] * SATS_TO_WEI
110+
111+
balance = int(rethrpc.eth_getBalance(f"0x{evm_addr}"), 16)
112+
print(f"Balance after deposit: {balance}")
113+
114+
net_balance = balance - original_balance
115+
assert net_balance == deposit_amount, f"invalid deposit amount: {net_balance}"
116+
117+
wait_until(
118+
lambda: int(rethrpc.eth_blockNumber(), base=16) > current_block_num,
119+
error_with="not building blocks",
120+
timeout=EVM_WAIT_TIME * 2,
121+
)
122+
123+
balance = int(rethrpc.eth_getBalance(f"0x{evm_addr}"), 16)
124+
net_balance = balance - original_balance
125+
assert (
126+
net_balance == deposit_amount
127+
), f"deposit processed multiple times, extra: {balance - original_balance - deposit_amount}"
128+
129+
# Scan the L2 blocks where the deposits were included
130+
start_block = 1
131+
end_block = int(rethrpc.eth_blockNumber(), base=16) + 1
132+
for block_num in range(start_block, end_block):
133+
block = rethrpc.eth_getBlockByNumber(hex(block_num), False)
134+
withdrawals = block.get("withdrawals", None)
135+
if withdrawals is not None and len(withdrawals) != 0:
136+
return block_num, btc_txn_id
137+
138+
return None, btc_txn_id

0 commit comments

Comments
 (0)