zkSync block revert
异常场景
注意:无法回滚已执行的高度,否则报Attempt to revert already executed blocks
此时,强制停止 prover,并发送交易, 制造落后场景
查询最新数据
zk f cargo run --bin block_reverter --release -- print-suggested-values --json
返回数据中包含几个信息
- committed 最新高度
- verified 已验证高度
- executed 本地已执行高度
- last_executed_l1_batch_number: 推荐回滚高度
- nonce: 执行交易nonce
- priority_fee: 推荐fee
2023-09-13T10:25:08.901399Z INFO zksync_core::block_reverter: Last L1 batch numbers on contract: committed 1171, verified 1170, executed 1170
{"last_executed_l1_batch_number":1170,"nonce":3867,"priority_fee":1000000000}
此时链上最新高度为committed:1171
测试回滚
先停止下zksync_server/zksync_external_node
合约回滚
1171回滚到1170
cd $ZKSYNC_HOME && zk f cargo run --bin block_reverter --release -- send-eth-transaction --l1-batch-number 1170 --nonce 3871 --priority-fee-per-gas 1000000000
此时会向合约发送revertBlocks交易,无需手动执行合约
此时再次查询
zk f cargo run --bin block_reverter --release -- print-suggested-values --json
此时链上最新高度为committed:1170
本地数据库回滚
注意:需要先停止下zksync_server/zksync_external_node, 否则报 ./db/main/tree/LOCK
cd $ZKSYNC_HOME && zk f cargo run --bin block_reverter --release -- rollback-db --l1-batch-number 1170 --rollback-postgres --rollback-tree --rollback-sk-cache
附加
core/bin/zksync_core/src/bin/block_reverter.rs
Command
- print-suggested-values
显示要使用的建议值。
- send-eth-transaction
将恢复事务发送到 L1。 - rollback-db
将内部数据库状态恢复到前一个块。 - clear-failed-transactions
清除失败的 L1 事务。
测试用例
core/tests/revert-test/tests/revert-and-restart.test.ts
const executedProcess = await utils.exec(
'cd $ZKSYNC_HOME && ' +
'RUST_LOG=off cargo run --bin block_reverter --release -- print-suggested-values --json'
// ^ Switch off logs to not pollute the output JSON
);
const suggestedValuesOutput = executedProcess.stdout;
const { lastL1BatchNumber, nonce, priorityFee } = parseSuggestedValues(suggestedValuesOutput);
expect(lastL1BatchNumber < blocksCommittedBeforeRevert, 'There should be at least one block for revert').to.be
.true;
console.log(
Reverting with parameters: last unreverted L1 batch number: ${lastL1BatchNumber}, nonce: ${nonce}, priorityFee: ${priorityFee}
);
console.log('Sending ETH transaction..');
await utils.spawn(
cd $ZKSYNC_HOME && cargo run --bin block_reverter --release -- send-eth-transaction --l1-batch-number ${lastL1BatchNumber} --nonce ${nonce} --priority-fee-per-gas ${priorityFee}
);
console.log('Rolling back DB..');
await utils.spawn(
cd $ZKSYNC_HOME && cargo run --bin block_reverter --release -- rollback-db --l1-batch-number ${lastL1BatchNumber} --rollback-postgres --rollback-tree --rollback-sk-cache
);
let blocksCommitted = await mainContract.getTotalBlocksCommitted();
expect(blocksCommitted.eq(lastL1BatchNumber), 'Revert on contract was unsuccessful').to.be.true;