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) |