ChallengeLib.bisectionChunkHash( _challengedSegmentStart, _challengedSegmentLength, _chainHashes[0], _oldEndHash ); verifySegmentProof(bisectionHash,_merkleNodes,_merkleRoute); 通过 merkle 树的路径检查确定起始状态和结束状态是上一次某个分割。 updateBisectionRoot(_chainHashes,_challengedSegmentStart,_challengedSegmentLength); 更新细分分割对应的 challengeState。 oneStepProveExecution 当不能分割后,挑战者提供初始状态(证明),并由 L1 进行相应的计算。计算的结果应该和提供的 _oldEndHash 不一致。不一致说明挑战者成功证明了之前的计算结果不对。 (uint64 gasUsed, uint256 totalMessagesRead, bytes32[4] memory proofFields) = executors[prover].executeStep( bridge, _initialMessagesRead, [_initialSendAcc,_initialLogAcc], _executionProof, _bufferProof ); 通过 executeStep 计算出正确的结束状态。executeStep 实现在 packages/arb-bridge-eth/contracts/arch/OneStepProofCommon.sol 中。核心是 executeOp 函数,针对当前的 context 读取 op,执行并更新状态。感兴趣的小伙伴可以自行查看。 rootHash = ChallengeLib.bisectionChunkHash( _challengedSegmentStart, _challengedSegmentLength, oneStepProofExecutionBefore( _initialMessagesRead, _initialSendAcc, _initialLogAcc, _initialState, proofFields ), _oldEndHash ); } verifySegmentProof(rootHash,_merkleNodes,_merkleRoute); 确定初始状态和结束状态是上一次挑战状态中的某个分割。初始状态由提供的证明(proof)计算获得。 require( _oldEndHash != oneStepProofExecutionAfter( _initialSendAcc, _initialLogAcc, _initialState, gasUsed, totalMessagesRead, proofFields ), “WRONG_END” ); 确认 _oldEndHash 和计算获得结束状态不一样。不一样才说明之前提交的结束状态是错误的。 _currentWin(); 计算完成后,确定胜利方。 总结Arbitrum 是 Layer2 Rollup 的一种方案。采用挑战机制确定 Rollup 状态的终局性。为了引入轻便挑战机制,Arbitrum 定义了 AVM,一种可以方便证明执行状态的虚拟机,并设计了 mini 语言和编译器。在 AVM 上模拟了 EVM 的执行环境,兼容 EVM。挑战时将执行过程进行 400 分分割,由 L1 执行少量指令确定状态是否正确。 (责任编辑:admin) |