initializeChallenge function initializeChallenge( IOneStepProof[] calldata_executors, address_resultReceiver, bytes32_executionHash, uint256_maxMessageCount, address_asserter, address_challenger, uint256_asserterTimeLeft, uint256_challengerTimeLeft, IBridge_bridge ) external override { ... asserter =_asserter; challenger =_challenger; ... turn = Turn.Challenger; challengeState =_executionHash; ... } initializeChallenge 确定挑战者和应战者,并确定需要挑战的状态(存储在 challengeState)。challengeState 是由一个和多个 bisectionChunk 状态 hash 组成的 merkle 树树根: 整个执行过程可以分割成多个小过程,每个小过程 (bisection) 由起始和结束的 gas 和状态来表示。 turn 用来记录交互顺序。turn = Turn.Challenger 表明在初始化挑战后,首先由 Challenger 发起分歧点分割。 bisectExecution bisectExecution 挑选之前分割片段,并如可能将片段进行再次分割: bisectExecution 的函数定义如下: function bisectExecution( bytes32[] calldata_merkleNodes, uint256_merkleRoute, uint256_challengedSegmentStart, uint256_challengedSegmentLength, bytes32_oldEndHash, uint256_gasUsedBefore, bytes32_assertionRest, bytes32[] calldata_chainHashes ) external onlyOnTurn { _chainHashes 是再次分割点的状态。如果需要再次分割,需要满足分割点的个数规定: uint256 private constant EXECUTION_BISECTION_DEGREE = 400; require( _chainHashes.length == bisectionDegree(_challengedSegmentLength, EXECUTION_BISECTION_DEGREE) + 1, “CUT_COUNT” ); 简单的说,每次分割,必须分割成 400 份。 _oldEndHash 是用来验证状态这次分割的分割片段是上一次分割中的某个。需要检查分割的有效性: require(_chainHashes[_chainHashes.length - 1] !=_oldEndHash, “SAME_END”); require( _chainHashes[0] == ChallengeLib.assertionHash(_gasUsedBefore,_assertionRest), “segment pre-fields” ); require(_chainHashes[0] != UNREACHABLE_ASSERTION, “UNREACHABLE_START”); require( _gasUsedBefore <_challengedSegmentStart.add(_challengedSegmentLength), “invalid segment length” ); 起始状态正确。这次分割不能超出上次分割范围,并且最后一个状态和上一个分割的结束状态不一样。 bytes32 bisectionHash = (责任编辑:admin) |