From c6694796828d3300cae173d971c760361e675866 Mon Sep 17 00:00:00 2001 From: billxu Date: Tue, 2 Apr 2024 10:46:49 +0800 Subject: [PATCH 1/9] modify the dispute game feature to 4ary, add unit tests --- .../src/dispute/FaultDisputeGame.sol | 377 ++++++++++++------ .../src/dispute/lib/LibPosition.sol | 6 + .../test/dispute/FaultDisputeGame.t.sol | 315 +++++++++++++++ 3 files changed, 570 insertions(+), 128 deletions(-) diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index 2f7eda6b73212..1085dda248899 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -17,6 +17,8 @@ import { LibClock } from "src/dispute/lib/LibUDT.sol"; import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeErrors.sol"; +error NotSupported(); + /// @title FaultDisputeGame /// @notice An implementation of the `IFaultDisputeGame` interface. contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { @@ -89,6 +91,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @notice Flag for the `initialize` function to prevent re-initialization. bool internal initialized; + /// @notice Bits of N-ary search + uint256 nBits; + /// @notice Semantic version. /// @custom:semver 0.7.1 string public constant version = "0.7.1"; @@ -226,107 +231,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @param _claim The claim at the next logical position in the game. /// @param _isAttack Whether or not the move is an attack or defense. function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable virtual { - // INVARIANT: Moves cannot be made unless the game is currently in progress. - if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); - - // Get the parent. If it does not exist, the call will revert with OOB. - ClaimData memory parent = claimData[_challengeIndex]; - - // Compute the position that the claim commits to. Because the parent's position is already - // known, we can compute the next position by moving left or right depending on whether - // or not the move is an attack or defense. - Position parentPos = parent.position; - Position nextPosition = parentPos.move(_isAttack); - uint256 nextPositionDepth = nextPosition.depth(); - - // INVARIANT: A defense can never be made against the root claim of either the output root game or any - // of the execution trace bisection subgames. This is because the root claim commits to the - // entire state. Therefore, the only valid defense is to do nothing if it is agreed with. - if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) { - revert CannotDefendRootClaim(); - } - - // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a - // claim at this depth is to perform a single instruction step on-chain via - // the `step` function to prove that the state transition produces an unexpected - // post-state. - if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded(); - - // When the next position surpasses the split depth (i.e., it is the root claim of an execution - // trace bisection sub-game), we need to perform some extra verification steps. - if (nextPositionDepth == SPLIT_DEPTH + 1) { - _verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack); - } - - // INVARIANT: The `msg.value` must be sufficient to cover the required bond. - if (getRequiredBond(nextPosition) > msg.value) revert InsufficientBond(); - - // Fetch the grandparent clock, if it exists. - // The grandparent clock should always exist unless the parent is the root claim. - Clock grandparentClock; - if (parent.parentIndex != type(uint32).max) { - grandparentClock = claimData[parent.parentIndex].clock; - } - - // Compute the duration of the next clock. This is done by adding the duration of the - // grandparent claim to the difference between the current block timestamp and the - // parent's clock timestamp. - Duration nextDuration = Duration.wrap( - uint64( - // First, fetch the duration of the grandparent claim. - grandparentClock.duration().raw() - // Second, add the difference between the current block timestamp and the - // parent's clock timestamp. - + block.timestamp - parent.clock.timestamp().raw() - ) - ); - - // INVARIANT: A move can never be made once its clock has exceeded `GAME_DURATION / 2` - // seconds of time. - if (nextDuration.raw() > GAME_DURATION.raw() >> 1) revert ClockTimeExceeded(); - - // Construct the next clock with the new duration and the current block timestamp. - Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp))); - - // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple - // claims at the same position may dispute the same challengeIndex. However, they must have different - // values. - ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex); - if (claims[claimHash]) revert ClaimAlreadyExists(); - claims[claimHash] = true; - - // Create the new claim. - claimData.push( - ClaimData({ - parentIndex: uint32(_challengeIndex), - // This is updated during subgame resolution - counteredBy: address(0), - claimant: msg.sender, - bond: uint128(msg.value), - claim: _claim, - position: nextPosition, - clock: nextClock - }) - ); - - // Update the subgame rooted at the parent claim. - subgames[_challengeIndex].push(claimData.length - 1); - - // Deposit the bond. - WETH.deposit{ value: msg.value }(); - - // Emit the appropriate event for the attack or defense. - emit Move(_challengeIndex, _claim, msg.sender); + revert NotSupported(); } /// @inheritdoc IFaultDisputeGame function attack(uint256 _parentIndex, Claim _claim) external payable { - move(_parentIndex, _claim, true); + revert NotSupported(); } /// @inheritdoc IFaultDisputeGame function defend(uint256 _parentIndex, Claim _claim) external payable { - move(_parentIndex, _claim, false); + revert NotSupported(); } /// @inheritdoc IFaultDisputeGame @@ -548,6 +463,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // Set the game's starting timestamp createdAt = Timestamp.wrap(uint64(block.timestamp)); + nBits = 2; // Set the game as initialized. initialized = true; } @@ -788,46 +704,13 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // Walk up the DAG until the ancestor's depth is equal to the split depth. uint256 currentDepth; - ClaimData storage execRootClaim = claim; while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) { uint256 parentIndex = claim.parentIndex; - - // If we're currently at the split depth + 1, we're at the root of the execution sub-game. - // We need to keep track of the root claim here to determine whether the execution sub-game was - // started with an attack or defense against the output leaf claim. - if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim; - claim = claimData[parentIndex]; claimIdx = parentIndex; } - - // Determine whether the start of the execution sub-game was an attack or defense to the output root - // above. This is important because it determines which claim is the starting output root and which - // is the disputed output root. - (Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position); - bool wasAttack = execRootPos.parent().raw() == outputPos.raw(); - - // Determine the starting and disputed output root indices. - // 1. If it was an attack, the disputed output root is `claim`, and the starting output root is - // elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`). - // 2. If it was a defense, the starting output root is `claim`, and the disputed output root is - // elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`). - if (wasAttack) { - // If this is an attack on the first output root (the block directly after genesis), the - // starting claim nor position exists in the tree. We leave these as 0, which can be easily - // identified due to 0 being an invalid Gindex. - if (outputPos.indexAtDepth() > 0) { - ClaimData storage starting = _findTraceAncestor(Position.wrap(outputPos.raw() - 1), claimIdx, true); - (startingClaim_, startingPos_) = (starting.claim, starting.position); - } else { - startingClaim_ = Claim.wrap(GENESIS_OUTPUT_ROOT.raw()); - } - (disputedClaim_, disputedPos_) = (claim.claim, claim.position); - } else { - ClaimData storage disputed = _findTraceAncestor(Position.wrap(outputPos.raw() + 1), claimIdx, true); - (startingClaim_, startingPos_) = (claim.claim, claim.position); - (disputedClaim_, disputedPos_) = (disputed.claim, disputed.position); - } + (startingPos_, startingClaim_) = findPreStateClaim(1 << nBits, claim.position, claimIdx); + (disputedPos_, disputedClaim_) = findPostStateClaim(1 << nBits, claim.position, claimIdx); } /// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame. @@ -863,4 +746,242 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos))); } } + + function attackAt(uint256 _parentIndex, Claim _claim, uint256 _attackBranch) public payable { + moveV2(_parentIndex, _claim, _attackBranch); + } + + // ClaimHash => attackBranch => Claim + mapping(Claim => mapping(uint256 => Claim)) internal claimHashToClaims; + + function setClaimHashClaims(Claim _claimHash, uint256 _attackBranch, Claim _claim) public { + claimHashToClaims[_claimHash][_attackBranch] = _claim; + } + + function getClaimFromClaimHash( + Claim claimsHash, + uint256 claimIndex + ) internal view returns (Claim) { + // TODO: retrieve the claim from the claimsHash + // Either: from EIP-4844 BLOB with point-evaluation proof or calldata with Merkle proof + return claimHashToClaims[claimsHash][claimIndex]; + } + + function findPreStateClaim( + uint256 _nary, + Position _pos, + uint256 _start + ) public view returns (Position pos_, Claim claim_) { + ClaimData storage ancestor_ = claimData[_start]; + uint256 pos = _pos.raw(); + while (pos % _nary == 0 && pos != 1) { + pos = pos / _nary; + if (type(uint32).max != ancestor_.parentIndex) { + ancestor_ = claimData[ancestor_.parentIndex]; + } + } + if (pos == 1) { + // S_0 + claim_ = ABSOLUTE_PRESTATE; + } else { + claim_ = getClaimFromClaimHash(ancestor_.claim, (pos - 1) % _nary); + pos = ancestor_.position.raw(); + } + return (Position.wrap(uint128(pos)), claim_); + } + + function findPostStateClaim( + uint256 _nary, + Position _pos, + uint256 _start + ) public view returns (Position pos_, Claim claim_) { + ClaimData storage ancestor_ = claimData[_start]; + uint256 pos = _pos.raw(); + // pos is _nary's multiple, while condition is false + // actually return the claim of _start + while ((pos + 1) % _nary == 0 && pos != 1) { + pos = pos / _nary; + if (type(uint32).max != ancestor_.parentIndex) { + ancestor_ = claimData[ancestor_.parentIndex]; + } + } + return (Position.wrap(uint128(pos)), getClaimFromClaimHash(ancestor_.claim, pos % _nary)); + } + + function stepV2( + uint256 _claimIndex, + uint256 _attackBranch, + bytes calldata _stateData, + bytes calldata _proof + ) + public + virtual + { + // INVARIANT: Steps cannot be made unless the game is currently in progress. + if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); + + // Get the parent. If it does not exist, the call will revert with OOB. + ClaimData storage parent = claimData[_claimIndex]; + + // Pull the parent position out of storage. + Position parentPos = parent.position; + // Determine the position of the step. + Position stepPos = parentPos.moveN(nBits, _attackBranch); + + // INVARIANT: A step cannot be made unless the move position is 1 below the `MAX_GAME_DEPTH` + if (stepPos.depth() != MAX_GAME_DEPTH + nBits) revert InvalidParent(); + + // Determine the expected pre & post states of the step. + Claim preStateClaim; + Position preStatePosition; + Claim postStateClaim; + Position postStatePosition; + //ClaimData storage postState; + + // TODO: deal with SPLIT_DEPTH + //(preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, stepPos, _claimIndex); + (preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, parentPos, _claimIndex); + //(postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, stepPos, _claimIndex); + (postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, parentPos, _claimIndex); + + // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the + // preimage of the prestate claim hash. + // We ignore the highest order byte of the digest because it is used to + // indicate the VM Status and is added after the digest is computed. + if (keccak256(_stateData) << 8 != preStateClaim.raw() << 8) revert InvalidPrestate(); + + // Compute the local preimage context for the step. + Hash uuid = _findLocalContext(_claimIndex); + + // INVARIANT: If a step is an attack, the poststate is valid if the step produces + // the same poststate hash as the parent claim's value. + // If a step is a defense: + // 1. If the parent claim and the found post state agree with each other + // (depth diff % 2 == 0), the step is valid if it produces the same + // state hash as the post state's claim. + // 2. If the parent claim and the found post state disagree with each other + // (depth diff % 2 != 0), the parent cannot be countered unless the step + // produces the same state hash as `postState.claim`. + // SAFETY: While the `attack` path does not need an extra check for the post + // state's depth in relation to the parent, we don't need another + // branch because (n - n) % 2 == 0. + bool validStep = VM.step(_stateData, _proof, uuid.raw()) == postStateClaim.raw(); + bool parentPostAgree = (parentPos.depth() - postStatePosition.depth()) % 2 == 0; + if (parentPostAgree == validStep) revert ValidStep(); + + // INVARIANT: A step cannot be made against a claim for a second time. + if (parent.counteredBy != address(0)) revert DuplicateStep(); + + // Set the parent claim as countered. We do not need to append a new claim to the game; + // instead, we can just set the existing parent as countered. + parent.counteredBy = msg.sender; + } + + function moveV2(uint256 _challengeIndex, Claim _claim, uint256 _attackBranch) public payable { + // For N = 4 (bisec), + // 1. _attackBranch == 0 (attack) + // 2. _attackBranch == 1 (attack) + // 3. _attackBranch == 2 (attack) + // 4. _attackBranch == 3 (attack) + require(_attackBranch < (1 << nBits)); + + // INVARIANT: Moves cannot be made unless the game is currently in progress. + if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); + + // Get the parent. If it does not exist, the call will revert with OOB. + ClaimData memory parent = claimData[_challengeIndex]; + + // Compute the position that the claim commits to. Because the parent's position is already + // known, we can compute the next position by moving left or right depending on whether + // or not the move is an attack or defense. + Position parentPos = parent.position; + Position nextPosition = parentPos.moveN(nBits, _attackBranch); + uint256 nextPositionDepth = nextPosition.depth(); + + // INVARIANT: A defense can never be made against the root claim of either the output root game or any + // of the execution trace bisection subgames. This is because the root claim commits to the + // entire state. Therefore, the only valid defense is to do nothing if it is agreed with. + //if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && _attackBranch != 0) { + //revert CannotDefendRootClaim(); + //} + // todo bill modify, nextPositionDepth == SPLIT_DEPTH + 2 check ?? + // root claim only one branch + if (_challengeIndex == 0 && _attackBranch != 0) { + revert CannotDefendRootClaim(); + } + + // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a + // claim at this depth is to perform a single instruction step on-chain via + // the `step` function to prove that the state transition produces an unexpected + // post-state. + if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded(); + + // When the next position surpasses the split depth (i.e., it is the root claim of an execution + // trace bisection sub-game), we need to perform some extra verification steps. + // TODO + //if (nextPositionDepth == SPLIT_DEPTH + 1) { + //_verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack); + //} + + // INVARIANT: The `msg.value` must be sufficient to cover the required bond. + if (getRequiredBond(nextPosition) > msg.value) revert InsufficientBond(); + + // Fetch the grandparent clock, if it exists. + // The grandparent clock should always exist unless the parent is the root claim. + Clock grandparentClock; + if (parent.parentIndex != type(uint32).max) { + grandparentClock = claimData[parent.parentIndex].clock; + } + + // Compute the duration of the next clock. This is done by adding the duration of the + // grandparent claim to the difference between the current block timestamp and the + // parent's clock timestamp. + Duration nextDuration = Duration.wrap( + uint64( + // First, fetch the duration of the grandparent claim. + grandparentClock.duration().raw() + // Second, add the difference between the current block timestamp and the + // parent's clock timestamp. + + block.timestamp - parent.clock.timestamp().raw() + ) + ); + + // INVARIANT: A move can never be made once its clock has exceeded `GAME_DURATION / 2` + // seconds of time. + if (nextDuration.raw() > GAME_DURATION.raw() >> 1) revert ClockTimeExceeded(); + + // Construct the next clock with the new duration and the current block timestamp. + Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp))); + + // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple + // claims at the same position may dispute the same challengeIndex. However, they must have different + // values. + // todo bill modify + ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex); + if (claims[claimHash]) revert ClaimAlreadyExists(); + claims[claimHash] = true; + + // Create the new claim. + claimData.push( + ClaimData({ + parentIndex: uint32(_challengeIndex), + // This is updated during subgame resolution + counteredBy: address(0), + claimant: msg.sender, + bond: uint128(msg.value), + claim: _claim, + position: nextPosition, + clock: nextClock + }) + ); + + // Update the subgame rooted at the parent claim. + subgames[_challengeIndex].push(claimData.length - 1); + + // Deposit the bond. + WETH.deposit{ value: msg.value }(); + + // Emit the appropriate event for the attack or defense. + emit Move(_challengeIndex, _claim, msg.sender); + } } diff --git a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol index abf79fb51b062..3c4ca681e354b 100644 --- a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol +++ b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol @@ -177,6 +177,12 @@ library LibPosition { } } + function moveN(Position _position, uint256 _bits, uint256 _branch) internal pure returns (Position move_) { + assembly { + move_ := shl(_bits, or(_branch, _position)) + } + } + /// @notice Get the value of a `Position` type in the form of the underlying uint128. /// @param _position The position to get the value of. /// @return raw_ The value of the `position` as a uint128 type. diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index ae54cbbdb2b1e..0cc78be5602b5 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -1004,6 +1004,321 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { } } +contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { + /// @dev The root claim of the game. + Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10))); + + /// @dev The preimage of the absolute prestate claim + bytes internal absolutePrestateData; + /// @dev The absolute prestate of the trace. + Claim internal absolutePrestate; + + /// @dev Minimum bond value that covers all possible moves. + uint256 internal constant MIN_BOND = 50 ether; + + function setUp() public override { + absolutePrestateData = abi.encode(0); + absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED); + + super.setUp(); + super.init({ + rootClaim: ROOT_CLAIM, + absolutePrestate: absolutePrestate, + l2BlockNumber: 0x10, + genesisBlockNumber: 0, + genesisOutputRoot: Hash.wrap(bytes32(0)) + }); + } + + //////////////////////////////////////////////////////////////// + // `IDisputeGame` Implementation Tests // + //////////////////////////////////////////////////////////////// + + /// @dev Tests that the constructor of the `FaultDisputeGame` reverts when the `_splitDepth` + /// parameter is greater than or equal to the `MAX_GAME_DEPTH` + function test_constructor_wrongArgs_reverts(uint256 _splitDepth) public { + AlphabetVM alphabetVM = new AlphabetVM(absolutePrestate, new PreimageOracle(0, 0)); + + // Test that the constructor reverts when the `_splitDepth` parameter is greater than or equal + // to the `MAX_GAME_DEPTH` parameter. + _splitDepth = bound(_splitDepth, 2 ** 3, type(uint256).max); + vm.expectRevert(InvalidSplitDepth.selector); + new FaultDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _genesisBlockNumber: 0, + _genesisOutputRoot: Hash.wrap(bytes32(0)), + _maxGameDepth: 2 ** 3, + _splitDepth: _splitDepth, + _gameDuration: Duration.wrap(7 days), + _vm: alphabetVM, + _weth: DelayedWETH(payable(address(0))), + _l2ChainId: 10 + }); + } + + /// @dev Tests that the game's root claim is set correctly. + function test_rootClaim_succeeds() public { + assertEq(gameProxy.rootClaim().raw(), ROOT_CLAIM.raw()); + } + + /// @dev Tests that the game's extra data is set correctly. + function test_extraData_succeeds() public { + assertEq(gameProxy.extraData(), extraData); + } + + /// @dev Tests that the game's starting timestamp is set correctly. + function test_createdAt_succeeds() public { + assertEq(gameProxy.createdAt().raw(), block.timestamp); + } + + /// @dev Tests that the game's type is set correctly. + function test_gameType_succeeds() public { + assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw()); + } + + /// @dev Tests that the game's data is set correctly. + function test_gameData_succeeds() public { + (GameType gameType, Claim rootClaim, bytes memory _extraData) = gameProxy.gameData(); + + assertEq(gameType.raw(), GAME_TYPE.raw()); + assertEq(rootClaim.raw(), ROOT_CLAIM.raw()); + assertEq(_extraData, extraData); + } + + //////////////////////////////////////////////////////////////// + // `IFaultDisputeGame` Implementation Tests // + //////////////////////////////////////////////////////////////// + + /// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured genesis + /// block number + function testFuzz_initialize_cannotProposeGenesis_reverts(uint256 _blockNumber) public { + _blockNumber = bound(_blockNumber, 0, gameProxy.genesisBlockNumber()); + + Claim claim = _dummyClaim(); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim)); + gameProxy = + FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, abi.encode(_blockNumber))))); + } + + /// @dev Tests that the proxy receives ETH from the dispute game factory. + function test_initialize_receivesETH_succeeds(uint128 _value) public { + _value = uint128(bound(_value, gameProxy.getRequiredBond(Position.wrap(1)), type(uint128).max)); + vm.deal(address(this), _value); + + assertEq(address(gameProxy).balance, 0); + gameProxy = FaultDisputeGame( + payable(address(disputeGameFactory.create{ value: _value }(GAME_TYPE, ROOT_CLAIM, abi.encode(1)))) + ); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), _value); + } + + /// @dev Tests that the game cannot be initialized with extra data > 64 bytes long (root claim + l2 block number + /// concatenated) + function testFuzz_initialize_extraDataTooLong_reverts(uint256 _extraDataLen) public { + // The `DisputeGameFactory` will pack the root claim and the extra data into a single array, which is enforced + // to be at least 64 bytes long. + // We bound the upper end to 23.5KB to ensure that the minimal proxy never surpasses the contract size limit + // in this test, as CWIA proxies store the immutable args in their bytecode. + // [33 bytes, 23.5 KB] + _extraDataLen = bound(_extraDataLen, 33, 23_500); + bytes memory _extraData = new bytes(_extraDataLen); + + // Assign the first 32 bytes in `extraData` to a valid L2 block number passed genesis. + uint256 genesisBlockNumber = gameProxy.genesisBlockNumber(); + assembly { + mstore(add(_extraData, 0x20), add(genesisBlockNumber, 1)) + } + + Claim claim = _dummyClaim(); + vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector)); + gameProxy = FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, _extraData)))); + } + + /// @dev Tests that the game is initialized with the correct data. + function test_initialize_correctData_succeeds() public { + // Assert that the root claim is initialized correctly. + ( + uint32 parentIndex, + address counteredBy, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ) = gameProxy.claimData(0); + assertEq(parentIndex, type(uint32).max); + assertEq(counteredBy, address(0)); + assertEq(claimant, DEFAULT_SENDER); + assertEq(bond, 0); + assertEq(claim.raw(), ROOT_CLAIM.raw()); + assertEq(position.raw(), 1); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))).raw()); + + // Assert that the `createdAt` timestamp is correct. + assertEq(gameProxy.createdAt().raw(), block.timestamp); + + // Assert that the blockhash provided is correct. + assertEq(gameProxy.l1Head().raw(), blockhash(block.number - 1)); + } + + /// @dev Tests that the game cannot be initialized twice. + function test_initialize_onlyOnce_succeeds() public { + vm.expectRevert(AlreadyInitialized.selector); + gameProxy.initialize(); + } + + /// @dev Tests that the bond during the bisection game depths is correct. + function test_getRequiredBond_succeeds() public { + for (uint64 i = 0; i < uint64(gameProxy.splitDepth()); i++) { + Position pos = LibPosition.wrap(i, 0); + uint256 bond = gameProxy.getRequiredBond(pos); + + // Reasonable approximation for a max depth of 8. + uint256 expected = 0.08 ether; + for (uint64 j = 0; j < i; j++) { + expected = expected * 217456; + expected = expected / 100000; + } + + assertApproxEqAbs(bond, expected, 0.01 ether); + } + } + + /// @dev Tests that the bond at a depth greater than the maximum game depth reverts. + function test_getRequiredBond_outOfBounds_reverts() public { + Position pos = LibPosition.wrap(uint64(gameProxy.maxGameDepth() + 1), 0); + vm.expectRevert(GameDepthExceeded.selector); + gameProxy.getRequiredBond(pos); + } + + function test_stepAttackDummyClaim_lastAttackFalse_succeeds() public { + // Give the test contract some ether + vm.deal(address(this), 1000 ether); + + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); + gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(4), 3); + + bytes memory claimData3 = abi.encode(5, 5); + Claim preState_ = Claim.wrap(keccak256(claimData3)); + + Claim hash = _dummyClaim(); + gameProxy.setClaimHashClaims(hash, 0, preState_); + gameProxy.setClaimHashClaims(hash, 1, _dummyClaim()); + gameProxy.setClaimHashClaims(hash, 2, _dummyClaim()); + gameProxy.setClaimHashClaims(hash, 3, _dummyClaim()); + + gameProxy.attackAt{ value: MIN_BOND }(2, hash, 2); + gameProxy.attackAt{ value: MIN_BOND }(3, _dummyClaimHashAndSetClaims(4), 1); + gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 4, 0); + gameProxy.stepV2(4, 0, claimData3, hex""); + + // Ensure that the step successfully countered the leaf claim. + (, address counteredBy,,,,,) = gameProxy.claimData(4); + assertEq(counteredBy, address(this)); + } + + function test_stepAttackDummyClaim_lastAttackTrue_reverts() public { + // Give the test contract some ether + vm.deal(address(this), 1000 ether); + + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); + gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(4), 3); + + bytes memory claimData3 = abi.encode(5, 5); + Claim preState_ = Claim.wrap(keccak256(claimData3)); + Claim postState_ = Claim.wrap(gameImpl.vm().step(claimData3, hex"", bytes32(0))); + + Claim hash2 = _dummyClaim(); + gameProxy.setClaimHashClaims(hash2, 0, preState_); + gameProxy.setClaimHashClaims(hash2, 1, _dummyClaim()); + gameProxy.setClaimHashClaims(hash2, 2, _dummyClaim()); + gameProxy.setClaimHashClaims(hash2, 3, _dummyClaim()); + gameProxy.attackAt{ value: MIN_BOND }(2, hash2, 2); + + Claim hash3 = _dummyClaim(); + gameProxy.setClaimHashClaims(hash3, 0, postState_); + gameProxy.setClaimHashClaims(hash3, 1, _dummyClaim()); + gameProxy.setClaimHashClaims(hash3, 2, _dummyClaim()); + gameProxy.setClaimHashClaims(hash3, 3, _dummyClaim()); + gameProxy.attackAt{ value: MIN_BOND }(3, hash3, 1); + gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 4, 0); + + vm.expectRevert(ValidStep.selector); + gameProxy.stepV2(4, 0, claimData3, hex""); + } + + /// @dev Static unit test for the correctness an uncontested root resolution. + function test_resolve_rootUncontested_succeeds() public { + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + } + + /// @dev Static unit test for the correctness an uncontested root resolution. + function test_resolve_rootUncontestedClockNotExpired_succeeds() public { + vm.warp(block.timestamp + 3 days + 12 hours); + vm.expectRevert(ClockNotExpired.selector); + gameProxy.resolveClaim(0); + } + + /// @dev Static unit test asserting that resolve reverts when the absolute root + /// subgame has not been resolved. + function test_resolve_rootUncontestedButUnresolved_reverts() public { + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + vm.expectRevert(OutOfOrderResolution.selector); + gameProxy.resolve(); + } + + /// @dev Static unit test asserting that resolve reverts when the game state is + /// not in progress. + function test_resolve_notInProgress_reverts() public { + uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); + + // Replace the game status in storage. It exists in slot 0 at offset 16. + uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); + uint256 offset = 16 << 3; + uint256 mask = 0xFF << offset; + // Replace the byte in the slot value with the challenger wins status. + slot = (slot & ~mask) | (chalWins << offset); + + vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot)); + vm.expectRevert(GameNotInProgress.selector); + gameProxy.resolveClaim(0); + } + + /// @dev Static unit test for the correctness of resolving a single attack game state. + function test_resolve_rootContested_succeeds() public { + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); + } + + + /// @dev Helper to return a pseudo-random claim + function _dummyClaim() internal view returns (Claim) { + return Claim.wrap(keccak256(abi.encode(gasleft()))); + } + + function _dummyClaimHashAndSetClaims(uint256 nary) internal returns (Claim) { + Claim hash = _dummyClaim(); + for (uint256 i; i < nary; i++) { + gameProxy.setClaimHashClaims(hash, i, _dummyClaim()); + } + return hash; + } + + /// @dev Helper to get the localized key for an identifier in the context of the game proxy. + function _getKey(uint256 _ident, bytes32 _localContext) internal view returns (bytes32) { + bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext)); + return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248)); + } +} + contract FaultDispute_1v1_Actors_Test is FaultDisputeGame_Init { /// @dev The honest actor DisputeActor internal honest; From b3b70113cb4be70bef6c66e29b1937b82a1518d7 Mon Sep 17 00:00:00 2001 From: billxu Date: Tue, 16 Apr 2024 01:07:59 +0800 Subject: [PATCH 2/9] fix findPreStateClaim & findPostStateClaim --- .../src/dispute/FaultDisputeGame.sol | 19 +++++++++---------- .../test/dispute/FaultDisputeGame.t.sol | 15 ++++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index 1085dda248899..cc60d5365f5d8 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -775,10 +775,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ClaimData storage ancestor_ = claimData[_start]; uint256 pos = _pos.raw(); while (pos % _nary == 0 && pos != 1) { - pos = pos / _nary; - if (type(uint32).max != ancestor_.parentIndex) { + if (pos != _pos.raw()) { ancestor_ = claimData[ancestor_.parentIndex]; } + pos = pos / _nary; } if (pos == 1) { // S_0 @@ -797,13 +797,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ) public view returns (Position pos_, Claim claim_) { ClaimData storage ancestor_ = claimData[_start]; uint256 pos = _pos.raw(); - // pos is _nary's multiple, while condition is false - // actually return the claim of _start + pos = pos / _nary; while ((pos + 1) % _nary == 0 && pos != 1) { - pos = pos / _nary; - if (type(uint32).max != ancestor_.parentIndex) { + if (pos != _pos.raw() / _nary) { ancestor_ = claimData[ancestor_.parentIndex]; } + pos = pos / _nary; } return (Position.wrap(uint128(pos)), getClaimFromClaimHash(ancestor_.claim, pos % _nary)); } @@ -839,10 +838,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { //ClaimData storage postState; // TODO: deal with SPLIT_DEPTH - //(preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, stepPos, _claimIndex); - (preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, parentPos, _claimIndex); - //(postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, stepPos, _claimIndex); - (postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, parentPos, _claimIndex); + (preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, stepPos, _claimIndex); + //(preStatePosition, preStateClaim) = findPreStateClaim(1 << nBits, parentPos, _claimIndex); + (postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, stepPos, _claimIndex); + //(postStatePosition, postStateClaim) = findPostStateClaim(1 << nBits, parentPos, _claimIndex); // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the // preimage of the prestate claim hash. diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index 0cc78be5602b5..4c844025d550b 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -1197,8 +1197,8 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { // Give the test contract some ether vm.deal(address(this), 1000 ether); - gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); - gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(4), 3); + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(3), 0); + gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(3), 3); bytes memory claimData3 = abi.encode(5, 5); Claim preState_ = Claim.wrap(keccak256(claimData3)); @@ -1207,10 +1207,9 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { gameProxy.setClaimHashClaims(hash, 0, preState_); gameProxy.setClaimHashClaims(hash, 1, _dummyClaim()); gameProxy.setClaimHashClaims(hash, 2, _dummyClaim()); - gameProxy.setClaimHashClaims(hash, 3, _dummyClaim()); gameProxy.attackAt{ value: MIN_BOND }(2, hash, 2); - gameProxy.attackAt{ value: MIN_BOND }(3, _dummyClaimHashAndSetClaims(4), 1); + gameProxy.attackAt{ value: MIN_BOND }(3, _dummyClaimHashAndSetClaims(3), 1); gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 4, 0); gameProxy.stepV2(4, 0, claimData3, hex""); @@ -1223,8 +1222,8 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { // Give the test contract some ether vm.deal(address(this), 1000 ether); - gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); - gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(4), 3); + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(3), 0); + gameProxy.attackAt{ value: MIN_BOND }(1, _dummyClaimHashAndSetClaims(3), 3); bytes memory claimData3 = abi.encode(5, 5); Claim preState_ = Claim.wrap(keccak256(claimData3)); @@ -1234,14 +1233,12 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { gameProxy.setClaimHashClaims(hash2, 0, preState_); gameProxy.setClaimHashClaims(hash2, 1, _dummyClaim()); gameProxy.setClaimHashClaims(hash2, 2, _dummyClaim()); - gameProxy.setClaimHashClaims(hash2, 3, _dummyClaim()); gameProxy.attackAt{ value: MIN_BOND }(2, hash2, 2); Claim hash3 = _dummyClaim(); gameProxy.setClaimHashClaims(hash3, 0, postState_); gameProxy.setClaimHashClaims(hash3, 1, _dummyClaim()); gameProxy.setClaimHashClaims(hash3, 2, _dummyClaim()); - gameProxy.setClaimHashClaims(hash3, 3, _dummyClaim()); gameProxy.attackAt{ value: MIN_BOND }(3, hash3, 1); gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 4, 0); @@ -1290,7 +1287,7 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { /// @dev Static unit test for the correctness of resolving a single attack game state. function test_resolve_rootContested_succeeds() public { - gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(4), 0); + gameProxy.attackAt{ value: MIN_BOND }(0, _dummyClaimHashAndSetClaims(3), 0); vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); From 90c8dce30465ee94f1ec2bdb498df906ab5111cd Mon Sep 17 00:00:00 2001 From: billxu Date: Fri, 26 Apr 2024 15:12:14 +0800 Subject: [PATCH 3/9] update --- op-e2e/faultproofs/simple_test.go | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 op-e2e/faultproofs/simple_test.go diff --git a/op-e2e/faultproofs/simple_test.go b/op-e2e/faultproofs/simple_test.go new file mode 100644 index 0000000000000..24f832c8f53ba --- /dev/null +++ b/op-e2e/faultproofs/simple_test.go @@ -0,0 +1,55 @@ +package faultproofs + +import ( + "context" + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestSimple_ChallengerWins(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, common.Hash{0xff}) + game.LogGameData(ctx) + + // The dispute game should have a zero balance + balance := game.WethBalance(ctx, game.Addr()) + require.Zero(t, balance.Uint64()) + + //alice := sys.Cfg.Secrets.Addresses().Alice + + // Grab the root claim + claim := game.RootClaim(ctx) + opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) + game.StartChallenger(ctx, "sequencer", "Challenger", opts) + game.LogGameData(ctx) + + // Perform a few moves + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + + claim = claim.Attack(ctx, common.Hash{}) + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + + /* + *claim = claim.Attack(ctx, common.Hash{}) + *game.LogGameData(ctx) + *_ = claim.WaitForCounterClaim(ctx) + */ + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} From 972a4c72ce830255d1d0b1a7c0dd6c5e979930e3 Mon Sep 17 00:00:00 2001 From: billxu Date: Sat, 27 Apr 2024 01:39:24 +0800 Subject: [PATCH 4/9] add faultproofs e2e test --- op-e2e/faultproofs/simple_test.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/op-e2e/faultproofs/simple_test.go b/op-e2e/faultproofs/simple_test.go index 24f832c8f53ba..b40ca2f137a8c 100644 --- a/op-e2e/faultproofs/simple_test.go +++ b/op-e2e/faultproofs/simple_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestSimple_ChallengerWins(t *testing.T) { +func TestSimple_Alphabet_ChallengerWins(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -53,3 +53,24 @@ func TestSimple_ChallengerWins(t *testing.T) { game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.LogGameData(ctx) } + +func TestSimple_Cannon_ChallengerWins(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 3, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + claim := game.DisputeLastBlock(ctx) + + // Create the root of the cannon trace. + claim = claim.Attack(ctx, common.Hash{0x01}) + game.LogGameData(ctx) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} From 5cdf10d28f9bef40325b0dec7d0ffebb5b6a13b9 Mon Sep 17 00:00:00 2001 From: billxu Date: Tue, 30 Apr 2024 10:53:24 +0800 Subject: [PATCH 5/9] modify DisputeBlock, support Nary=4 --- op-e2e/e2eutils/disputegame/helper.go | 4 ++ .../disputegame/output_game_helper.go | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 568d9d6fe5880..99fc0c6d122cd 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -167,11 +167,13 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string logger := testlog.Logger(h.t, log.LevelInfo).New("role", "OutputCannonGameHelper") rollupClient := h.system.RollupClient(l2Node) + // 区块号 extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber, cfg) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() + // 创建DisputeGameFactory合约 tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { return h.factory.Create(opts, cannonGameType, rootClaim, extraData) }) @@ -181,6 +183,8 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string h.require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[1]) h.require.NoError(err) + + // 准备DisputeGame合约 game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client) h.require.NoError(err) diff --git a/op-e2e/e2eutils/disputegame/output_game_helper.go b/op-e2e/e2eutils/disputegame/output_game_helper.go index d078a5f814f88..fec20e5cd3283 100644 --- a/op-e2e/e2eutils/disputegame/output_game_helper.go +++ b/op-e2e/e2eutils/disputegame/output_game_helper.go @@ -142,6 +142,59 @@ func (g *OutputGameHelper) DisputeBlock(ctx context.Context, disputeBlockNum uin return claim } +func (g *OutputGameHelper) DisputeBlockV2(ctx context.Context, disputeBlockNum uint64) *ClaimHelper { + dishonestValue := g.GetClaimValue(ctx, 0) + correctRootClaim := g.correctOutputRoot(ctx, types.NewPositionFromGIndex(big.NewInt(1))) + rootIsValid := dishonestValue == correctRootClaim + if rootIsValid { + // Ensure that the dishonest actor is actually posting invalid roots. + // Otherwise, the honest challenger will defend our counter and ruin everything. + dishonestValue = common.Hash{0xff, 0xff, 0xff} + } + pos := types.NewPositionFromGIndex(big.NewInt(1)) + getClaimValue := func(parentClaim *ClaimHelper, claimPos types.Position) common.Hash { + claimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(claimPos) + g.require.NoError(err, "failed to calculate claim block number") + if claimBlockNum < disputeBlockNum { + // Use the correct output root for all claims prior to the dispute block number + // This pushes the game to dispute the last block in the range + return g.correctOutputRoot(ctx, claimPos) + } + if rootIsValid == parentClaim.AgreesWithOutputRoot() { + // We are responding to a parent claim that agrees with a valid root, so we're being dishonest + return dishonestValue + } else { + // Otherwise we must be the honest actor so use the correct root + return g.correctOutputRoot(ctx, claimPos) + } + } + + tmp_pos := types.NewPositionFromGIndex(big.NewInt(2)) + g.t.Logf("tmp_pos.Attack befor pos: %v", tmp_pos) + tmp_pos = tmp_pos.Attack() + g.t.Logf("tmp_pos.Attack after pos: %v", tmp_pos) + tmp_pos = tmp_pos.Defend() + g.t.Logf("tmp_pos.Defend after tmp_pos: %v", tmp_pos) + + claim := g.RootClaim(ctx) + for !claim.IsOutputRootLeaf(ctx) { + parentClaimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) + g.require.NoError(err, "failed to calculate parent claim block number") + if parentClaimBlockNum >= disputeBlockNum { + g.t.Logf("pos.Attack befor pos: %v", pos) + pos = pos.Attack() + g.t.Logf("pos.Attack after pos: %v", pos) + claim = claim.Attack(ctx, getClaimValue(claim, pos)) + } else { + g.t.Logf("pos.Defend befor pos: %v", pos) + pos = pos.Defend() + g.t.Logf("pos.Defend after pos: %v", pos) + claim = claim.Defend(ctx, getClaimValue(claim, pos)) + } + } + return claim +} + func (g *OutputGameHelper) RootClaim(ctx context.Context) *ClaimHelper { claim := g.getClaim(ctx, 0) return newClaimHelper(g, 0, claim) From 09fda9f46183d526071101304b50fb8f35d69857 Mon Sep 17 00:00:00 2001 From: billxu Date: Tue, 30 Apr 2024 21:42:58 +0800 Subject: [PATCH 6/9] modify position --- op-challenger/game/fault/types/position.go | 7 +++++++ op-e2e/e2eutils/disputegame/helper.go | 5 ++--- op-e2e/e2eutils/disputegame/output_game_helper.go | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/op-challenger/game/fault/types/position.go b/op-challenger/game/fault/types/position.go index 85d1b1ccd750b..5a4ceb6b4439e 100644 --- a/op-challenger/game/fault/types/position.go +++ b/op-challenger/game/fault/types/position.go @@ -133,6 +133,13 @@ func (p Position) Defend() Position { return p.parent().move(true).move(false) } +func (p Position) MoveN(bits uint, branch *big.Int) Position { + move := new(big.Int) + move.Or(branch, p.ToGIndex()) + move.Lsh(move, bits) + return NewPositionFromGIndex(move) +} + func (p Position) Print(maxDepth Depth) { fmt.Printf("GIN: %4b\tTrace Position is %4b\tTrace Depth is: %d\tTrace Index is: %d\n", p.ToGIndex(), p.indexAtDepth, p.depth, p.TraceIndex(maxDepth)) } diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 99fc0c6d122cd..9c1aee4b419fd 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -167,13 +167,13 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string logger := testlog.Logger(h.t, log.LevelInfo).New("role", "OutputCannonGameHelper") rollupClient := h.system.RollupClient(l2Node) - // 区块号 + // 区块号 l2BlockNumber extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber, cfg) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() - // 创建DisputeGameFactory合约 + // 调用DisputeGameFactory合约的Create方法, 创建一个DisputeGame合约 tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { return h.factory.Create(opts, cannonGameType, rootClaim, extraData) }) @@ -184,7 +184,6 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[1]) h.require.NoError(err) - // 准备DisputeGame合约 game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client) h.require.NoError(err) diff --git a/op-e2e/e2eutils/disputegame/output_game_helper.go b/op-e2e/e2eutils/disputegame/output_game_helper.go index fec20e5cd3283..cbaa60efc0ddc 100644 --- a/op-e2e/e2eutils/disputegame/output_game_helper.go +++ b/op-e2e/e2eutils/disputegame/output_game_helper.go @@ -94,7 +94,7 @@ func (g *OutputGameHelper) GenesisBlockNum(ctx context.Context) uint64 { } func (g *OutputGameHelper) DisputeLastBlock(ctx context.Context) *ClaimHelper { - return g.DisputeBlock(ctx, g.L2BlockNum(ctx)) + return g.DisputeBlockV2(ctx, g.L2BlockNum(ctx)) } // DisputeBlock posts claims from both the honest and dishonest actor to progress the output root part of the game @@ -152,6 +152,7 @@ func (g *OutputGameHelper) DisputeBlockV2(ctx context.Context, disputeBlockNum u dishonestValue = common.Hash{0xff, 0xff, 0xff} } pos := types.NewPositionFromGIndex(big.NewInt(1)) + g.t.Logf("init pos: %v", pos) getClaimValue := func(parentClaim *ClaimHelper, claimPos types.Position) common.Hash { claimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(claimPos) g.require.NoError(err, "failed to calculate claim block number") @@ -169,14 +170,19 @@ func (g *OutputGameHelper) DisputeBlockV2(ctx context.Context, disputeBlockNum u } } + g.t.Logf("SplitDepth:%v, MaxDepth:%v", g.SplitDepth(ctx), g.MaxDepth(ctx)) + g.t.Logf("disputeBlockNum: %v", disputeBlockNum) tmp_pos := types.NewPositionFromGIndex(big.NewInt(2)) g.t.Logf("tmp_pos.Attack befor pos: %v", tmp_pos) + g.t.Logf("tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(0))) tmp_pos = tmp_pos.Attack() g.t.Logf("tmp_pos.Attack after pos: %v", tmp_pos) + g.t.Logf("tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(1))) tmp_pos = tmp_pos.Defend() g.t.Logf("tmp_pos.Defend after tmp_pos: %v", tmp_pos) claim := g.RootClaim(ctx) + g.t.Logf("root claim: %v", claim) for !claim.IsOutputRootLeaf(ctx) { parentClaimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) g.require.NoError(err, "failed to calculate parent claim block number") From 615250795e4cef1ec03e1a749119596ee7dd868a Mon Sep 17 00:00:00 2001 From: billxu Date: Wed, 1 May 2024 00:55:40 +0800 Subject: [PATCH 7/9] e2e Nary=4 --- op-bindings/bindings/faultdisputegame.go | 9 ++- op-challenger/game/fault/types/position.go | 4 +- op-e2e/e2eutils/disputegame/claim_helper.go | 5 ++ .../disputegame/output_game_helper.go | 73 +++++++++++++------ op-e2e/faultproofs/simple_test.go | 10 ++- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/op-bindings/bindings/faultdisputegame.go b/op-bindings/bindings/faultdisputegame.go index 268139c492167..33e552e64953d 100644 --- a/op-bindings/bindings/faultdisputegame.go +++ b/op-bindings/bindings/faultdisputegame.go @@ -30,8 +30,8 @@ var ( // FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract. var FaultDisputeGameMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_genesisBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_genesisOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"},{\"name\":\"_weth\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"_l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"absolutePrestate\",\"inputs\":[],\"outputs\":[{\"name\":\"absolutePrestate_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_execLeafIdx\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"claimCredit\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"counteredBy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bond\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimedBondFlag\",\"inputs\":[],\"outputs\":[{\"name\":\"claimedBondFlag_\",\"type\":\"uint128\",\"internalType\":\"uint128\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"credit\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameDuration\",\"inputs\":[],\"outputs\":[{\"name\":\"gameDuration_\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisBlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisOutputRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisOutputRoot_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRequiredBond\",\"inputs\":[{\"name\":\"_position\",\"type\":\"uint128\",\"internalType\":\"Position\"}],\"outputs\":[{\"name\":\"requiredBond_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"l1Head_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2ChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"l2ChainId_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maxGameDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"maxGameDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolvedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"splitDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"splitDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vm\",\"inputs\":[],\"outputs\":[{\"name\":\"vm_\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"weth\",\"inputs\":[],\"outputs\":[{\"name\":\"weth_\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumGameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyInitialized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BondTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAboveSplit\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DuplicateStep\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBond\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLocalIdent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSplitDepth\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoCreditToClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]", - Bin: "0x6101c06040523480156200001257600080fd5b5060405162004808380380620048088339810160408190526200003591620000c6565b858510620000565760405163e62ccf3960e01b815260040160405180910390fd5b63ffffffff90991661016052608097909752610120959095526101409390935260a09190915260c0526001600160401b031660e0526001600160a01b039081166101005216610180526101a05262000177565b80516001600160a01b0381168114620000c157600080fd5b919050565b6000806000806000806000806000806101408b8d031215620000e757600080fd5b8a5163ffffffff81168114620000fc57600080fd5b809a505060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b015160018060401b03811681146200013d57600080fd5b93506200014d60e08c01620000a9565b92506200015e6101008c01620000a9565b91506101208b015190509295989b9194979a5092959850565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051614551620002b76000396000818161069b01526124fd01526000818161033e01528181610acb015281816113a4015281816117960152613a3b01526000818161051a015261259701526000818161044f01526136e70152600081816101ff0152818161148201526123d20152600081816102ea01528181611e4d01526121a90152600081816106ee01528181610fcf01526126f501526000818161072101528181610dbc01528181610e8501528181611ca8015281816123a801528181612b3601528181613273015281816133a1015281816134a901526135850152600081816107c301528181610e28015281816119060152818161198c01528181611b970152611cc90152600081816104df0152611d5f01526145516000f3fe6080604052600436106101e75760003560e01c80638d450a951161010e578063d6ae3cd5116100a7578063f3f7214e11610079578063fa24f74311610061578063fa24f74314610790578063fa315aa9146107b4578063fdffbb28146107e757005b8063f3f7214e14610745578063f8f43ff61461077057005b8063d6ae3cd51461068c578063d8cc1a3c146106bf578063e1f0c376146106df578063ec5e63081461071257005b8063c55cd0c7116100e0578063c55cd0c7146105a1578063c6f0308c146105b4578063cf09e0d01461063e578063d5d44d801461065f57005b80638d450a95146104d0578063bbdc02db14610503578063bcef3b5514610544578063c395e1ca1461058157005b8063609d33341161018057806368800abf1161015257806368800abf146104405780638129fc1c146104735780638980e0cc1461047b5780638b85902b1461049057005b8063609d3334146103b857806360e27464146103cd578063632247ea146103ed5780636361506d1461040057005b806335fef567116101b957806335fef567146102c85780633a768463146102db5780633fc8cef31461032f57806354fd4d501461036257005b80630356fe3a146101f057806319effeb414610232578063200d2ed2146102785780632810e1d6146102b357005b366101ee57005b005b3480156101fc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561023e57600080fd5b5060005461025f9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610229565b34801561028457600080fd5b506000546102a690700100000000000000000000000000000000900460ff1681565b6040516102299190613e16565b3480156102bf57600080fd5b506102a66107fa565b6101ee6102d6366004613e57565b6109f7565b3480156102e757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610229565b34801561033b57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030a565b34801561036e57600080fd5b506103ab6040518060400160405280600581526020017f302e372e3100000000000000000000000000000000000000000000000000000081525081565b6040516102299190613ee4565b3480156103c457600080fd5b506103ab610a07565b3480156103d957600080fd5b506101ee6103e8366004613f19565b610a1a565b6101ee6103fb366004613f52565b610bc6565b34801561040c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561021f565b34801561044c57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b6101ee61143e565b34801561048757600080fd5b5060015461021f565b34801561049c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561021f565b3480156104dc57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b34801561050f57600080fd5b5060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610229565b34801561055057600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561021f565b34801561058d57600080fd5b5061021f61059c366004613f87565b611859565b6101ee6105af366004613e57565b611a43565b3480156105c057600080fd5b506105d46105cf366004613fb9565b611a4f565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e001610229565b34801561064a57600080fd5b5060005461025f9067ffffffffffffffff1681565b34801561066b57600080fd5b5061021f61067a366004613f19565b60026020526000908152604090205481565b34801561069857600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b3480156106cb57600080fd5b506101ee6106da36600461401b565b611ae6565b3480156106eb57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061025f565b34801561071e57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b34801561075157600080fd5b506040516fffffffffffffffffffffffffffffffff8152602001610229565b34801561077c57600080fd5b506101ee61078b3660046140a5565b61211b565b34801561079c57600080fd5b506107a5612595565b604051610229939291906140d1565b3480156107c057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021f565b6101ee6107f5366004613fb9565b6125f2565b600080600054700100000000000000000000000000000000900460ff16600281111561082857610828613de7565b1461085f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff1661089b576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106108c7576108c76140ff565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614610902576001610905565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156109b6576109b6613de7565b0217905560028111156109cb576109cb613de7565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610a0382826000610bc6565b5050565b6060610a1560406020612a53565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003610a7f576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015610b0f57600080fd5b505af1158015610b23573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610b81576040519150601f19603f3d011682016040523d82523d6000602084013e610b86565b606091505b5050905080610bc1576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610bf257610bf2613de7565b14610c29576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610c3e57610c3e6140ff565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610d039083908690612aea16565b90506000610da3826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610de55750610de27f0000000000000000000000000000000000000000000000000000000000000000600261415d565b81145b8015610def575084155b15610e26576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610e80576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eab7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b8103610ebd57610ebd86888588612af2565b34610ec783611859565b1115610eff576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610f5f576001856000015163ffffffff1681548110610f2e57610f2e6140ff565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c0850151600090610f839067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642610fad610f76856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610fc1919061415d565b610fcb9190614175565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff8216111561103e576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff16156110bc576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506113519190614175565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b1580156113e957600080fd5b505af11580156113fd573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b600554610100900460ff1615611480576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013511611537576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b606636111561154e5763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b1580156117dc57600080fd5b505af11580156117f0573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010017905550565b6000806118f8836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f000000000000000000000000000000000000000000000000000000000000000081111561195e576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc200600061197983836141bb565b9050670de0b6b3a764000060006119b0827f00000000000000000000000000000000000000000000000000000000000000006141cf565b905060006119ce6119c9670de0b6b3a7640000866141cf565b612cb3565b905060006119dc8484612f0e565b905060006119ea8383612f5d565b905060006119f782612f8b565b90506000611a1682611a11670de0b6b3a76400008f6141cf565b613173565b90506000611a248b83612f5d565b9050611a30818d6141cf565b9f9e505050505050505050505050505050565b610a0382826001610bc6565b60018181548110611a5f57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115611b1257611b12613de7565b14611b49576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611b5e57611b5e6140ff565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611bbd7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b611c59826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611c9a576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611d8957611ced7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614175565b6001901b611d0c846fffffffffffffffffffffffffffffffff166131ad565b67ffffffffffffffff16611d20919061420c565b15611d5d57611d54611d4560016fffffffffffffffffffffffffffffffff8716614220565b865463ffffffff166000613253565b60030154611d7f565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611db3565b60038501549150611db0611d456fffffffffffffffffffffffffffffffff86166001614251565b90505b600882901b60088a8a604051611dca929190614285565b6040518091039020901b14611e0b576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e168c613337565b90506000611e25836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced3290611e9f908f908f908f908f908a906004016142de565b6020604051808303816000875af1158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee29190614318565b600485015491149150600090600290611f8d906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612029896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6120339190614331565b61203d9190614352565b67ffffffffffffffff161590508115158103612085576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156120dc576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff16600281111561214757612147613de7565b1461217e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061218d86613366565b935093509350935060006121a385858585613793565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612212573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122369190614379565b90506001890361232e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84612292367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af1158015612304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123289190614318565b5061258a565b6002890361235a5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489612292565b600389036123865773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487612292565b600489036124bf5760006123cc6fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000000613852565b6123f6907f000000000000000000000000000000000000000000000000000000000000000061415d565b61240190600161415d565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612494573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b89190614318565b505061258a565b60058903612558576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a4016122e5565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606125eb610a07565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561261e5761261e613de7565b14612655576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001828154811061266a5761266a6140ff565b6000918252602082206005919091020160048101549092506126ac90700100000000000000000000000000000000900460401c67ffffffffffffffff16610f76565b60048301549091506000906126de90700100000000000000000000000000000000900467ffffffffffffffff16610f76565b6126e89042614331565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166127228284614396565b67ffffffffffffffff1611612763576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015612783575060055460ff165b156127ba576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801580156127c757508515155b1561282c578454640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156127fa5781612816565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506128228188613907565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b8381101561297257600085828154811061285d5761285d6140ff565b60009182526020808320909101548083526004909152604090912054909150156128b3576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600182815481106128c8576128c86140ff565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff16158015612921575060048101546fffffffffffffffffffffffffffffffff908116908516115b1561295f576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b50508061296b906143b9565b9050612841565b506129ba73ffffffffffffffffffffffffffffffffffffffff83161561299857826129b4565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613907565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416021787556000888152600460205260408120612a1691613dad565b8760000361282257600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b60606000612a8a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900361415d565b90508267ffffffffffffffff1667ffffffffffffffff811115612aaf57612aaf6143f1565b6040519080825280601f01601f191660200182016040528015612ad9576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000612b116fffffffffffffffffffffffffffffffff84166001614251565b90506000612b2182866001613253565b9050600086901a8380612c145750612b5a60027f000000000000000000000000000000000000000000000000000000000000000061420c565b6004830154600290612bfe906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612c089190614352565b67ffffffffffffffff16145b15612c6c5760ff811660011480612c2e575060ff81166002145b612c67576040517ff40239db0000000000000000000000000000000000000000000000000000000081526004810188905260240161152e565b612caa565b60ff811615612caa576040517ff40239db0000000000000000000000000000000000000000000000000000000081526004810188905260240161152e565b50505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213612d1257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202612f4b57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b600081600019048311820215612f7b5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d78213612fb957919050565b680755bf798b4a1bf1e58212612fd75763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60006131a4670de0b6b3a76400008361318b86612cb3565b6131959190614420565b61319f91906144dc565b612f8b565b90505b92915050565b60008061323a837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261329c576132976fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000613a93565b6132b7565b6132b7856fffffffffffffffffffffffffffffffff16613c51565b9050600184815481106132cc576132cc6140ff565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff82811691161461332f57815460018054909163ffffffff1690811061331a5761331a6140ff565b906000526020600020906005020191506132dd565b509392505050565b600080600080600061334886613366565b935093509350935061335c84848484613793565b9695505050505050565b6000806000806000859050600060018281548110613386576133866140ff565b600091825260209091206004600590920201908101549091507f00000000000000000000000000000000000000000000000000000000000000009061345d906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161349e576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000090613565906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1692508211156135e157825463ffffffff166135ab7f0000000000000000000000000000000000000000000000000000000000000000600161415d565b83036135b5578391505b600181815481106135c8576135c86140ff565b90600052602060002090600502019350809450506134a2565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff1661364a613635856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff16149050801561372f576000613682836fffffffffffffffffffffffffffffffff166131ad565b67ffffffffffffffff1611156136e55760006136bc6136b460016fffffffffffffffffffffffffffffffff8616614220565b896001613253565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a506137099050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750613785565b60006137516136b46fffffffffffffffffffffffffffffffff85166001614251565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff841681036137f95782826040516020016137dc9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b60405160208183030381529060405280519060200120905061384a565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b6000806138df847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613977576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff841660009081526020919091526040812080548392906139ea90849061415d565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613a7f57600080fd5b505af1158015612caa573d6000803e3d6000fd5b600081613b32846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613b73576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b7c83613c51565b905081613c1b826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16116131a7576131a4613c3883600161415d565b6fffffffffffffffffffffffffffffffff831690613cfd565b60008119600183011681613ce5827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080613d8a847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190613dcb9190613dce565b50565b5b80821115613de35760008155600101613dcf565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613e51577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215613e6a57600080fd5b50508035926020909101359150565b6000815180845260005b81811015613e9f57602081850181015186830182015201613e83565b81811115613eb1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006131a46020830184613e79565b73ffffffffffffffffffffffffffffffffffffffff81168114613dcb57600080fd5b600060208284031215613f2b57600080fd5b8135613f3681613ef7565b9392505050565b80358015158114613f4d57600080fd5b919050565b600080600060608486031215613f6757600080fd5b8335925060208401359150613f7e60408501613f3d565b90509250925092565b600060208284031215613f9957600080fd5b81356fffffffffffffffffffffffffffffffff81168114613f3657600080fd5b600060208284031215613fcb57600080fd5b5035919050565b60008083601f840112613fe457600080fd5b50813567ffffffffffffffff811115613ffc57600080fd5b60208301915083602082850101111561401457600080fd5b9250929050565b6000806000806000806080878903121561403457600080fd5b8635955061404460208801613f3d565b9450604087013567ffffffffffffffff8082111561406157600080fd5b61406d8a838b01613fd2565b9096509450606089013591508082111561408657600080fd5b5061409389828a01613fd2565b979a9699509497509295939492505050565b6000806000606084860312156140ba57600080fd5b505081359360208301359350604090920135919050565b63ffffffff841681528260208201526060604082015260006140f66060830184613e79565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156141705761417061412e565b500190565b6000828210156141875761418761412e565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826141ca576141ca61418c565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156142075761420761412e565b500290565b60008261421b5761421b61418c565b500690565b60006fffffffffffffffffffffffffffffffff838116908316818110156142495761424961412e565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561427c5761427c61412e565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006142f2606083018789614295565b8281036020840152614305818688614295565b9150508260408301529695505050505050565b60006020828403121561432a57600080fd5b5051919050565b600067ffffffffffffffff838116908316818110156142495761424961412e565b600067ffffffffffffffff8084168061436d5761436d61418c565b92169190910692915050565b60006020828403121561438b57600080fd5b8151613f3681613ef7565b600067ffffffffffffffff80831681851680830382111561427c5761427c61412e565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036143ea576143ea61412e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156144615761446161412e565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561449c5761449c61412e565b600087129250878205871284841616156144b8576144b861412e565b878505871281841616156144ce576144ce61412e565b505050929093029392505050565b6000826144eb576144eb61418c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561453f5761453f61412e565b50059056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_genesisBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_genesisOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contract IBigStepper\"},{\"name\":\"_weth\",\"type\":\"address\",\"internalType\":\"contract IDelayedWETH\"},{\"name\":\"_l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"absolutePrestate\",\"inputs\":[],\"outputs\":[{\"name\":\"absolutePrestate_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_execLeafIdx\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"attackAt\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_attackBranch\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"claimCredit\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"counteredBy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bond\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimedBondFlag\",\"inputs\":[],\"outputs\":[{\"name\":\"claimedBondFlag_\",\"type\":\"uint128\",\"internalType\":\"uint128\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"credit\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"findPostStateClaim\",\"inputs\":[{\"name\":\"_nary\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_pos\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"_start\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"pos_\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"claim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"findPreStateClaim\",\"inputs\":[{\"name\":\"_nary\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_pos\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"_start\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"pos_\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"claim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameDuration\",\"inputs\":[],\"outputs\":[{\"name\":\"gameDuration_\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisBlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"genesisOutputRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"genesisOutputRoot_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRequiredBond\",\"inputs\":[{\"name\":\"_position\",\"type\":\"uint128\",\"internalType\":\"Position\"}],\"outputs\":[{\"name\":\"requiredBond_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"l1Head_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2ChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"l2ChainId_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maxGameDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"maxGameDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"moveV2\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_attackBranch\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enum GameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolvedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"setClaimHashClaims\",\"inputs\":[{\"name\":\"_claimHash\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_attackBranch\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"splitDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"splitDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enum GameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stepV2\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_attackBranch\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vm\",\"inputs\":[],\"outputs\":[{\"name\":\"vm_\",\"type\":\"address\",\"internalType\":\"contract IBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"weth\",\"inputs\":[],\"outputs\":[{\"name\":\"weth_\",\"type\":\"address\",\"internalType\":\"contract IDelayedWETH\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enum GameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyInitialized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BondTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAboveSplit\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DuplicateStep\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBond\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLocalIdent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSplitDepth\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoCreditToClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotSupported\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]", + Bin: "0x6101c06040523480156200001257600080fd5b5060405162004e7b38038062004e7b8339810160408190526200003591620000c6565b858510620000565760405163e62ccf3960e01b815260040160405180910390fd5b63ffffffff90991661016052608097909752610120959095526101409390935260a09190915260c0526001600160401b031660e0526001600160a01b039081166101005216610180526101a05262000177565b80516001600160a01b0381168114620000c157600080fd5b919050565b6000806000806000806000806000806101408b8d031215620000e757600080fd5b8a5163ffffffff81168114620000fc57600080fd5b809a505060208b0151985060408b0151975060608b0151965060808b0151955060a08b0151945060c08b015160018060401b03811681146200013d57600080fd5b93506200014d60e08c01620000a9565b92506200015e6101008c01620000a9565b91506101208b015190509295989b9194979a5092959850565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051614bd2620002a9600039600081816107c10152612dc201526000818161043c015281816110f9015281816115df01528181611b3d0152613fea0152600081816106530152612e5c0152600061054801526000818161028f0152818161182a0152612c970152600081816103e801528181611e6a015281816127120152612a6e01526000818161085601528181610d240152612fba0152600081816108890152818161256d01528181612c6d015281816139cf01528181613ace0152613bd501526000818161092b01528181610bba01528181611cb7015281816121d70152818161225d0152818161245c015261258e0152600081816106180152818161126a01526126240152614bd26000f3fe6080604052600436106102775760003560e01c80638980e0cc11610156578063d6ae3cd5116100bf578063f3f7214e11610079578063fa24f74311610061578063fa24f743146108f8578063fa315aa91461091c578063fdffbb281461094f57005b8063f3f7214e146108ad578063f8f43ff6146108d857005b8063d8cc1a3c116100a7578063d8cc1a3c14610827578063e1f0c37614610847578063ec5e63081461087a57005b8063d6ae3cd5146107b2578063d7a327de146107e557005b8063c395e1ca11610110578063c6f0308c116100f8578063c6f0308c146106da578063cf09e0d014610764578063d5d44d801461078557005b8063c395e1ca146106ba578063c55cd0c7146103c657005b80638d450a951161013e5780638d450a9514610609578063bbdc02db1461063c578063bcef3b551461067d57005b80638980e0cc146105b45780638b85902b146105c957005b80633fc8cef3116101f85780636361506d116101b25780637acc0a8a1161019a5780637acc0a8a1461056c5780638129fc1c1461058c5780638594b6c11461059457005b80636361506d146104f957806368800abf1461053957005b8063609d3334116101e0578063609d3334146104b657806360e27464146104cb578063632247ea146104eb57005b80633fc8cef31461042d57806354fd4d501461046057005b8063217a82031161024957806329b171b51161023157806329b171b5146103b357806335fef567146103c65780633a768463146103d957005b8063217a8203146103565780632810e1d61461039e57005b80630356fe3a1461028057806312a41c4f146102c257806319effeb4146102d5578063200d2ed21461031b57005b3661027e57005b005b34801561028c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b61027e6102d03660046143bc565b610962565b3480156102e157600080fd5b506000546103029068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102b9565b34801561032757600080fd5b5060005461034990700100000000000000000000000000000000900460ff1681565b6040516102b99190614420565b34801561036257600080fd5b50610376610371366004614481565b611193565b604080516fffffffffffffffffffffffffffffffff90931683526020830191909152016102b9565b3480156103aa57600080fd5b506103496112dc565b61027e6103c13660046143bc565b6114d9565b61027e6103d43660046144b6565b6114e9565b3480156103e557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b9565b34801561043957600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610408565b34801561046c57600080fd5b506104a96040518060400160405280600581526020017f302e372e3100000000000000000000000000000000000000000000000000000081525081565b6040516102b99190614543565b3480156104c257600080fd5b506104a961151b565b3480156104d757600080fd5b5061027e6104e6366004614578565b61152e565b61027e6103d43660046145a5565b34801561050557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356102af565b34801561054557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102af565b34801561057857600080fd5b50610376610587366004614481565b6116d5565b61027e6117e6565b3480156105a057600080fd5b5061027e6105af36600461461a565b611c05565b3480156105c057600080fd5b506001546102af565b3480156105d557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356102af565b34801561061557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102af565b34801561064857600080fd5b5060405163ffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016102b9565b34801561068957600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356102af565b3480156106c657600080fd5b506102af6106d53660046146a4565b61212a565b3480156106e657600080fd5b506106fa6106f53660046146bf565b612314565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e0016102b9565b34801561077057600080fd5b506000546103029067ffffffffffffffff1681565b34801561079157600080fd5b506102af6107a0366004614578565b60026020526000908152604090205481565b3480156107be57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102af565b3480156107f157600080fd5b5061027e6108003660046146d8565b600092835260076020908152604080852067ffffffffffffffff9094168552929052912055565b34801561083357600080fd5b5061027e6108423660046146fd565b6123ab565b34801561085357600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610302565b34801561088657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102af565b3480156108b957600080fd5b506040516fffffffffffffffffffffffffffffffff81526020016102b9565b3480156108e457600080fd5b5061027e6108f3366004614726565b6129e0565b34801561090457600080fd5b5061090d612e5a565b6040516102b993929190614752565b34801561092857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102af565b61027e61095d3660046146bf565b612eb7565b6006546001901b8167ffffffffffffffff161061097e57600080fd5b60008054700100000000000000000000000000000000900460ff1660028111156109aa576109aa6143f1565b146109e1576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600184815481106109f6576109f6614780565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c08401526006549294509291610abe91849190879061331816565b90506000610b5e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16905086158015610b81575067ffffffffffffffff851615155b15610bb8576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610c12576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34610c1c8361212a565b1115610c54576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610cb4576001856000015163ffffffff1681548110610c8357610c83614780565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c0850151600090610cd89067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642610d02610ccb856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610d1691906147de565b610d2091906147f6565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff82161115610d93576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff1615610e11576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506110a691906147f6565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b15801561113e57600080fd5b505af1158015611152573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b6000806000600184815481106111ab576111ab614780565b9060005260206000209060050201905060006111d6866fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1690505b6111f5878261483c565b158015611203575080600114155b15611260576fffffffffffffffffffffffffffffffff8616811461124f57815460018054909163ffffffff1690811061123e5761123e614780565b906000526020600020906005020191505b6112598782614850565b90506111eb565b80600103611290577f000000000000000000000000000000000000000000000000000000000000000092506112d1565b60038201546112b490886112a56001856147f6565b6112af919061483c565b613320565b60048301549093506fffffffffffffffffffffffffffffffff1690505b925050935093915050565b600080600054700100000000000000000000000000000000900460ff16600281111561130a5761130a6143f1565b14611341576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff1661137d576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106113a9576113a9614780565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff16146113e45760016113e7565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff90911617700100000000000000000000000000000000836002811115611498576114986143f1565b0217905560028111156114ad576114ad6143f1565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b6114e4838383610962565b505050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60606115296040602061334b565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003611593576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b15801561162357600080fd5b505af1158015611637573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611695576040519150601f19603f3d011682016040523d82523d6000602084013e61169a565b606091505b50509050806114e4576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000600184815481106116ed576116ed614780565b906000526020600020906005020190506000611718866fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff1690506117368782614850565b90505b866117458260016147de565b61174f919061483c565b15801561175d575080600114155b156117c35761177e876fffffffffffffffffffffffffffffffff8816614850565b81146117b257815460018054909163ffffffff169081106117a1576117a1614780565b906000526020600020906005020191505b6117bc8782614850565b9050611739565b806117d8836003015489846112af919061483c565b935093505050935093915050565b600554610100900460ff1615611828576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360400135116118de576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b60663611156118f55763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b158015611b8357600080fd5b505af1158015611b97573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600260065550600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60008054700100000000000000000000000000000000900460ff166002811115611c3157611c316143f1565b14611c68576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611c7d57611c7d614780565b6000918252602090912060059091020160048101546006549192506fffffffffffffffffffffffffffffffff1690878217811b90611cdb907f00000000000000000000000000000000000000000000000000000000000000006147de565b611d77826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611db8576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080611dcf6006546001901b868f611193565b600654909550909350611de7906001901b868f6116d5565b92509050600884901b60088c8c604051611e02929190614864565b6040518091039020901b14611e43576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611e4e8e6133e2565b905060008373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663e14ced328f8f8f8f886040518663ffffffff1660e01b8152600401611eb49594939291906148bd565b6020604051808303816000875af1158015611ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef791906148f7565b14905060006002611f9a856fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6120368b6fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6120409190614910565b61204a9190614939565b67ffffffffffffffff161590508115158103612092576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8954640100000000900473ffffffffffffffffffffffffffffffffffffffff16156120e9576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505087547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1633640100000000021790975550505050505050505050505050565b6000806121c9836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f000000000000000000000000000000000000000000000000000000000000000081111561222f576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc200600061224a8383614850565b9050670de0b6b3a76400006000612281827f0000000000000000000000000000000000000000000000000000000000000000614960565b9050600061229f61229a670de0b6b3a764000086614960565b613411565b905060006122ad848461366c565b905060006122bb83836136bb565b905060006122c8826136e9565b905060006122e7826122e2670de0b6b3a76400008f614960565b6138d1565b905060006122f58b836136bb565b9050612301818d614960565b9f9e505050505050505050505050505050565b6001818154811061232457600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff1660028111156123d7576123d76143f1565b1461240e576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001878154811061242357612423614780565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506124827f000000000000000000000000000000000000000000000000000000000000000060016147de565b61251e826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461255f576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561264e576125b27f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006147f6565b6001901b6125d1846fffffffffffffffffffffffffffffffff16613909565b67ffffffffffffffff166125e5919061483c565b156126225761261961260a60016fffffffffffffffffffffffffffffffff871661499d565b865463ffffffff1660006139af565b60030154612644565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050612678565b6003850154915061267561260a6fffffffffffffffffffffffffffffffff861660016149c6565b90505b600882901b60088a8a60405161268f929190614864565b6040518091039020901b146126d0576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126db8c6133e2565b905060006126ea836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced3290612764908f908f908f908f908a906004016148bd565b6020604051808303816000875af1158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a791906148f7565b600485015491149150600090600290612852906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6128ee896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6128f89190614910565b6129029190614939565b67ffffffffffffffff16159050811515810361294a576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff16156129a1576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff166002811115612a0c57612a0c6143f1565b14612a43576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080612a5286613a93565b93509350935093506000612a6885858585613d42565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ad7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612afb91906149fa565b905060018903612bf35773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a84612b57367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af1158015612bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bed91906148f7565b50612e4f565b60028903612c1f5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489612b57565b60038903612c4b5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487612b57565b60048903612d84576000612c916fffffffffffffffffffffffffffffffff85167f0000000000000000000000000000000000000000000000000000000000000000613e01565b612cbb907f00000000000000000000000000000000000000000000000000000000000000006147de565b612cc69060016147de565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7d91906148f7565b5050612e4f565b60058903612e1d576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401612baa565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060612eb061151b565b9050909192565b60008054700100000000000000000000000000000000900460ff166002811115612ee357612ee36143f1565b14612f1a576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018281548110612f2f57612f2f614780565b600091825260208220600591909102016004810154909250612f7190700100000000000000000000000000000000900460401c67ffffffffffffffff16610ccb565b6004830154909150600090612fa390700100000000000000000000000000000000900467ffffffffffffffff16610ccb565b612fad9042614910565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c16612fe78284614a17565b67ffffffffffffffff1611613028576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015613048575060055460ff165b1561307f576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561308c57508515155b156130f1578454640100000000900473ffffffffffffffffffffffffffffffffffffffff16600081156130bf57816130db565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506130e78188613eb6565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b8381101561323757600085828154811061312257613122614780565b6000918252602080832090910154808352600490915260409091205490915015613178576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001828154811061318d5761318d614780565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff161580156131e6575060048101546fffffffffffffffffffffffffffffffff908116908516115b15613224576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b50508061323090614a3a565b9050613106565b5061327f73ffffffffffffffffffffffffffffffffffffffff83161561325d5782613279565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613eb6565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff84160217875560008881526004602052604081206132db91614365565b876000036130e757600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b909117901b90565b600082815260076020908152604080832067ffffffffffffffff851684529091529020545b92915050565b6060600061338284367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036147de565b90508267ffffffffffffffff1667ffffffffffffffff8111156133a7576133a7614a72565b6040519080825280601f01601f1916602001820160405280156133d1576020820181803683370190505b509150828160208401375092915050565b60008060008060006133f386613a93565b935093509350935061340784848484613d42565b9695505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b176000821361347057631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a7640000021582026136a957637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156136d95763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361371757919050565b680755bf798b4a1bf1e582126137355763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613902670de0b6b3a7640000836138e986613411565b6138f39190614aa1565b6138fd9190614b5d565b6136e9565b9392505050565b600080613996837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080826139f8576139f36fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000061404b565b613a13565b613a13856fffffffffffffffffffffffffffffffff16614209565b905060018481548110613a2857613a28614780565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff828116911614613a8b57815460018054909163ffffffff16908110613a7657613a76614780565b90600052602060002090600502019150613a39565b509392505050565b6000806000806000859050600060018281548110613ab357613ab3614780565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000090613b8a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613bcb576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b60048201547f000000000000000000000000000000000000000000000000000000000000000090613c91906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169150811115613cdc5781546001805463ffffffff9092169182908110613cc357613cc3614780565b9060005260206000209060050201925080935050613bce565b6006546004830154613d05916001901b906fffffffffffffffffffffffffffffffff1685611193565b6006546004850154919950919750613d34916001901b906fffffffffffffffffffffffffffffffff16856116d5565b979996985095945050505050565b60006fffffffffffffffffffffffffffffffff84168103613da8578282604051602001613d8b9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b604051602081830303815290604052805190602001209050613df9565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080613e8e847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613f26576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff84166000908152602091909152604081208054839290613f999084906147de565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b15801561402e57600080fd5b505af1158015614042573d6000803e3d6000fd5b50505050505050565b6000816140ea846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161412b576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61413483614209565b9050816141d3826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613345576139026141f08360016147de565b6fffffffffffffffffffffffffffffffff8316906142b5565b6000811960018301168161429d827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080614342847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b50805460008255906000526020600020908101906143839190614386565b50565b5b8082111561439b5760008155600101614387565b5090565b803567ffffffffffffffff811681146143b757600080fd5b919050565b6000806000606084860312156143d157600080fd5b83359250602084013591506143e86040850161439f565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061445b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b80356fffffffffffffffffffffffffffffffff811681146143b757600080fd5b60008060006060848603121561449657600080fd5b833592506144a660208501614461565b9150604084013590509250925092565b600080604083850312156144c957600080fd5b50508035926020909101359150565b6000815180845260005b818110156144fe576020818501810151868301820152016144e2565b81811115614510576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061390260208301846144d8565b73ffffffffffffffffffffffffffffffffffffffff8116811461438357600080fd5b60006020828403121561458a57600080fd5b813561390281614556565b803580151581146143b757600080fd5b6000806000606084860312156145ba57600080fd5b83359250602084013591506143e860408501614595565b60008083601f8401126145e357600080fd5b50813567ffffffffffffffff8111156145fb57600080fd5b60208301915083602082850101111561461357600080fd5b9250929050565b6000806000806000806080878903121561463357600080fd5b863595506146436020880161439f565b9450604087013567ffffffffffffffff8082111561466057600080fd5b61466c8a838b016145d1565b9096509450606089013591508082111561468557600080fd5b5061469289828a016145d1565b979a9699509497509295939492505050565b6000602082840312156146b657600080fd5b61390282614461565b6000602082840312156146d157600080fd5b5035919050565b6000806000606084860312156146ed57600080fd5b833592506144a66020850161439f565b6000806000806000806080878903121561471657600080fd5b8635955061464360208801614595565b60008060006060848603121561473b57600080fd5b505081359360208301359350604090920135919050565b63ffffffff8416815282602082015260606040820152600061477760608301846144d8565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156147f1576147f16147af565b500190565b600082821015614808576148086147af565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261484b5761484b61480d565b500690565b60008261485f5761485f61480d565b500490565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006148d1606083018789614874565b82810360208401526148e4818688614874565b9150508260408301529695505050505050565b60006020828403121561490957600080fd5b5051919050565b600067ffffffffffffffff83811690831681811015614931576149316147af565b039392505050565b600067ffffffffffffffff808416806149545761495461480d565b92169190910692915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614998576149986147af565b500290565b60006fffffffffffffffffffffffffffffffff83811690831681811015614931576149316147af565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156149f1576149f16147af565b01949350505050565b600060208284031215614a0c57600080fd5b815161390281614556565b600067ffffffffffffffff8083168185168083038211156149f1576149f16147af565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a6b57614a6b6147af565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615614ae257614ae26147af565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615614b1d57614b1d6147af565b60008712925087820587128484161615614b3957614b396147af565b87850587128184161615614b4f57614b4f6147af565b505050929093029392505050565b600082614b6c57614b6c61480d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614bc057614bc06147af565b50059056fea164736f6c634300080f000a", } // FaultDisputeGameABI is the input ABI used to generate the binding from. @@ -1031,6 +1031,11 @@ func (_FaultDisputeGame *FaultDisputeGameTransactor) Attack(opts *bind.TransactO return _FaultDisputeGame.contract.Transact(opts, "attack", _parentIndex, _claim) } +// Solidity: function attack(uint256 _parentIndex, bytes32 _claim, uint256 _attackBranch) payable returns() +func (_FaultDisputeGame *FaultDisputeGameTransactor) AttackAt(opts *bind.TransactOpts, _parentIndex *big.Int, _claim [32]byte, _attackBranch uint64) (*types.Transaction, error) { + return _FaultDisputeGame.contract.Transact(opts, "attackAt", _parentIndex, _claim, _attackBranch) +} + // Attack is a paid mutator transaction binding the contract method 0xc55cd0c7. // // Solidity: function attack(uint256 _parentIndex, bytes32 _claim) payable returns() diff --git a/op-challenger/game/fault/types/position.go b/op-challenger/game/fault/types/position.go index 5a4ceb6b4439e..68d067b02135d 100644 --- a/op-challenger/game/fault/types/position.go +++ b/op-challenger/game/fault/types/position.go @@ -133,9 +133,9 @@ func (p Position) Defend() Position { return p.parent().move(true).move(false) } -func (p Position) MoveN(bits uint, branch *big.Int) Position { +func (p Position) MoveN(bits uint, branch uint64) Position { move := new(big.Int) - move.Or(branch, p.ToGIndex()) + move.Or(big.NewInt(0).SetUint64(branch), p.ToGIndex()) move.Lsh(move, bits) return NewPositionFromGIndex(move) } diff --git a/op-e2e/e2eutils/disputegame/claim_helper.go b/op-e2e/e2eutils/disputegame/claim_helper.go index eff88db4240ab..b51b27caf22f4 100644 --- a/op-e2e/e2eutils/disputegame/claim_helper.go +++ b/op-e2e/e2eutils/disputegame/claim_helper.go @@ -108,6 +108,11 @@ func (c *ClaimHelper) Defend(ctx context.Context, value common.Hash, opts ...Mov return c.WaitForCounterClaim(ctx) } +func (c *ClaimHelper) AttackAt(ctx context.Context, value common.Hash, branch uint64, opts ...MoveOpt) *ClaimHelper { + c.game.AttackAt(ctx, c.index, value, branch, opts...) + return c.WaitForCounterClaim(ctx) +} + func (c *ClaimHelper) RequireDifferentClaimValue(other *ClaimHelper) { c.require.NotEqual(c.claim, other.claim, "should have posted different claims") } diff --git a/op-e2e/e2eutils/disputegame/output_game_helper.go b/op-e2e/e2eutils/disputegame/output_game_helper.go index cbaa60efc0ddc..094147f1799ad 100644 --- a/op-e2e/e2eutils/disputegame/output_game_helper.go +++ b/op-e2e/e2eutils/disputegame/output_game_helper.go @@ -152,7 +152,6 @@ func (g *OutputGameHelper) DisputeBlockV2(ctx context.Context, disputeBlockNum u dishonestValue = common.Hash{0xff, 0xff, 0xff} } pos := types.NewPositionFromGIndex(big.NewInt(1)) - g.t.Logf("init pos: %v", pos) getClaimValue := func(parentClaim *ClaimHelper, claimPos types.Position) common.Hash { claimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(claimPos) g.require.NoError(err, "failed to calculate claim block number") @@ -170,33 +169,40 @@ func (g *OutputGameHelper) DisputeBlockV2(ctx context.Context, disputeBlockNum u } } - g.t.Logf("SplitDepth:%v, MaxDepth:%v", g.SplitDepth(ctx), g.MaxDepth(ctx)) - g.t.Logf("disputeBlockNum: %v", disputeBlockNum) - tmp_pos := types.NewPositionFromGIndex(big.NewInt(2)) - g.t.Logf("tmp_pos.Attack befor pos: %v", tmp_pos) - g.t.Logf("tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(0))) - tmp_pos = tmp_pos.Attack() - g.t.Logf("tmp_pos.Attack after pos: %v", tmp_pos) - g.t.Logf("tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(1))) - tmp_pos = tmp_pos.Defend() - g.t.Logf("tmp_pos.Defend after tmp_pos: %v", tmp_pos) - + /* + *g.t.Logf("TestLog SplitDepth:%v, MaxDepth:%v", g.SplitDepth(ctx), g.MaxDepth(ctx)) + *g.t.Logf("TestLog disputeBlockNum: %v", disputeBlockNum) + *tmp_pos := types.NewPositionFromGIndex(big.NewInt(2)) + *g.t.Logf("TestLog tmp_pos.Attack befor pos: %v", tmp_pos) + *g.t.Logf("TestLog tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(0))) + *tmp_pos = tmp_pos.Attack() + *g.t.Logf("TestLog tmp_pos.Attack after pos: %v", tmp_pos) + *g.t.Logf("TestLog tmp_pos.MoveN after pos: %v", tmp_pos.MoveN(1, big.NewInt(1))) + *tmp_pos = tmp_pos.Defend() + *g.t.Logf("TestLog tmp_pos.Defend after tmp_pos: %v", tmp_pos) + */ + + // FaultDisputeGame 获取根节点 claim := g.RootClaim(ctx) - g.t.Logf("root claim: %v", claim) + g.t.Logf("TestLog init pos: %v", pos) + g.t.Logf("TestLog root claim: %v", claim) + // 通过pos的深度判断是否为output叶节点 + g.t.Logf("TestLog claim.position.Depth(): %v, position:%v", claim.position.Depth(), claim.position) for !claim.IsOutputRootLeaf(ctx) { parentClaimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) g.require.NoError(err, "failed to calculate parent claim block number") if parentClaimBlockNum >= disputeBlockNum { - g.t.Logf("pos.Attack befor pos: %v", pos) - pos = pos.Attack() - g.t.Logf("pos.Attack after pos: %v", pos) - claim = claim.Attack(ctx, getClaimValue(claim, pos)) + g.t.Logf("TestLog pos.Attack MoveN befor pos: %v", pos) + pos = pos.MoveN(2, 0) + g.t.Logf("TestLog pos.Attack MoveN after pos: %v", pos) + claim = claim.AttackAt(ctx, getClaimValue(claim, pos), 0) } else { - g.t.Logf("pos.Defend befor pos: %v", pos) - pos = pos.Defend() - g.t.Logf("pos.Defend after pos: %v", pos) - claim = claim.Defend(ctx, getClaimValue(claim, pos)) + g.t.Logf("TestLog pos.Defend MoveN befor pos: %v", pos) + pos = pos.MoveN(2, 3) + g.t.Logf("TestLog pos.Defend MoveN after pos: %v", pos) + claim = claim.AttackAt(ctx, getClaimValue(claim, pos), 3) } + g.t.Logf("TestLog claim.position.Depth(): %v, position:%v", claim.position.Depth(), claim.position) } return claim } @@ -633,6 +639,27 @@ func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim com } } +func (g *OutputGameHelper) AttackAt(ctx context.Context, claimIdx int64, claim common.Hash, branch uint64, opts ...MoveOpt) { + g.t.Logf("AttackAt claim %v with value %v, branch %v", claimIdx, claim, branch) + cfg := g.moveCfg(opts...) + + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + g.require.NoError(err, "Failed to get claim data") + pos := types.NewPositionFromGIndex(claimData.Position) + attackPos := pos.MoveN(2, branch) + transactOpts := g.makeBondedTransactOpts(ctx, attackPos.ToGIndex(), cfg.opts) + + err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { + return g.game.AttackAt(transactOpts, big.NewInt(claimIdx), claim, branch) + }) + if err != nil { + if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, attackPos, claim) { + return + } + g.require.NoErrorf(err, "AttackAt transaction failed. Game state: \n%v", g.gameData(ctx)) + } +} + func (g *OutputGameHelper) hasClaim(ctx context.Context, parentIdx int64, pos types.Position, value common.Hash) bool { claims := g.getAllClaims(ctx) for _, claim := range claims { @@ -801,6 +828,10 @@ func (g *OutputGameHelper) LogGameData(ctx context.Context) { g.t.Log(g.gameData(ctx)) } +func (g *OutputGameHelper) LogGameDataF(ctx context.Context, flag string) { + g.t.Logf("TestLog GameData %v, %v", flag, g.gameData(ctx)) +} + func (g *OutputGameHelper) Credit(ctx context.Context, addr common.Address) *big.Int { opts := &bind.CallOpts{Context: ctx} amt, err := g.game.Credit(opts, addr) diff --git a/op-e2e/faultproofs/simple_test.go b/op-e2e/faultproofs/simple_test.go index b40ca2f137a8c..7fcabba49f184 100644 --- a/op-e2e/faultproofs/simple_test.go +++ b/op-e2e/faultproofs/simple_test.go @@ -66,11 +66,13 @@ func TestSimple_Cannon_ChallengerWins(t *testing.T) { claim := game.DisputeLastBlock(ctx) // Create the root of the cannon trace. - claim = claim.Attack(ctx, common.Hash{0x01}) - game.LogGameData(ctx) + //claim = claim.Attack(ctx, common.Hash{0x01}) + claim = claim.AttackAt(ctx, common.Hash{0x01}, 0) + game.LogGameDataF(ctx, "AttackAt[0]") - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + t.Logf("TestLog GameDuration: %v", game.GameDuration(ctx)) + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx) * 2) require.NoError(t, wait.ForNextBlock(ctx, l1Client)) game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) - game.LogGameData(ctx) + game.LogGameDataF(ctx, "ChallengerWins") } From 024f562b98b9e6176cdce130930df6343e4db293 Mon Sep 17 00:00:00 2001 From: billxu Date: Wed, 1 May 2024 00:56:58 +0800 Subject: [PATCH 8/9] modify attackBranch, uint256 to uint64 --- .../src/dispute/FaultDisputeGame.sol | 16 ++++++++-------- .../src/dispute/lib/LibPosition.sol | 2 +- .../test/dispute/FaultDisputeGame.t.sol | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index cc60d5365f5d8..d34fb4a08d0ff 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -747,20 +747,20 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { } } - function attackAt(uint256 _parentIndex, Claim _claim, uint256 _attackBranch) public payable { + function attackAt(uint256 _parentIndex, Claim _claim, uint64 _attackBranch) public payable { moveV2(_parentIndex, _claim, _attackBranch); } // ClaimHash => attackBranch => Claim - mapping(Claim => mapping(uint256 => Claim)) internal claimHashToClaims; + mapping(Claim => mapping(uint64 => Claim)) internal claimHashToClaims; - function setClaimHashClaims(Claim _claimHash, uint256 _attackBranch, Claim _claim) public { + function setClaimHashClaims(Claim _claimHash, uint64 _attackBranch, Claim _claim) public { claimHashToClaims[_claimHash][_attackBranch] = _claim; } function getClaimFromClaimHash( Claim claimsHash, - uint256 claimIndex + uint64 claimIndex ) internal view returns (Claim) { // TODO: retrieve the claim from the claimsHash // Either: from EIP-4844 BLOB with point-evaluation proof or calldata with Merkle proof @@ -784,7 +784,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // S_0 claim_ = ABSOLUTE_PRESTATE; } else { - claim_ = getClaimFromClaimHash(ancestor_.claim, (pos - 1) % _nary); + claim_ = getClaimFromClaimHash(ancestor_.claim, uint64((pos - 1) % _nary)); pos = ancestor_.position.raw(); } return (Position.wrap(uint128(pos)), claim_); @@ -804,12 +804,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { } pos = pos / _nary; } - return (Position.wrap(uint128(pos)), getClaimFromClaimHash(ancestor_.claim, pos % _nary)); + return (Position.wrap(uint128(pos)), getClaimFromClaimHash(ancestor_.claim, uint64(pos % _nary))); } function stepV2( uint256 _claimIndex, - uint256 _attackBranch, + uint64 _attackBranch, bytes calldata _stateData, bytes calldata _proof ) @@ -876,7 +876,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { parent.counteredBy = msg.sender; } - function moveV2(uint256 _challengeIndex, Claim _claim, uint256 _attackBranch) public payable { + function moveV2(uint256 _challengeIndex, Claim _claim, uint64 _attackBranch) public payable { // For N = 4 (bisec), // 1. _attackBranch == 0 (attack) // 2. _attackBranch == 1 (attack) diff --git a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol index 3c4ca681e354b..70db0fa614bcb 100644 --- a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol +++ b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol @@ -177,7 +177,7 @@ library LibPosition { } } - function moveN(Position _position, uint256 _bits, uint256 _branch) internal pure returns (Position move_) { + function moveN(Position _position, uint256 _bits, uint64 _branch) internal pure returns (Position move_) { assembly { move_ := shl(_bits, or(_branch, _position)) } diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol index 4c844025d550b..915b835fada29 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -1303,7 +1303,7 @@ contract FaultDisputeGame4Ary_Test is FaultDisputeGame_Init { function _dummyClaimHashAndSetClaims(uint256 nary) internal returns (Claim) { Claim hash = _dummyClaim(); - for (uint256 i; i < nary; i++) { + for (uint64 i; i < nary; i++) { gameProxy.setClaimHashClaims(hash, i, _dummyClaim()); } return hash; From 46cd50f7317f626714f54477b58a178239d3f1e4 Mon Sep 17 00:00:00 2001 From: billxu Date: Wed, 1 May 2024 09:27:41 +0800 Subject: [PATCH 9/9] modify e2e faultproofs --- op-e2e/faultproofs/simple_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/op-e2e/faultproofs/simple_test.go b/op-e2e/faultproofs/simple_test.go index 7fcabba49f184..d4722efbaabed 100644 --- a/op-e2e/faultproofs/simple_test.go +++ b/op-e2e/faultproofs/simple_test.go @@ -65,11 +65,18 @@ func TestSimple_Cannon_ChallengerWins(t *testing.T) { require.NotNil(t, game) claim := game.DisputeLastBlock(ctx) + opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) + game.StartChallenger(ctx, "sequencer", "Challenger", opts) + game.LogGameData(ctx) + // Create the root of the cannon trace. //claim = claim.Attack(ctx, common.Hash{0x01}) claim = claim.AttackAt(ctx, common.Hash{0x01}, 0) game.LogGameDataF(ctx, "AttackAt[0]") + claim = claim.AttackAt(ctx, common.Hash{0x02}, 2) + game.LogGameDataF(ctx, "AttackAt[2]") + t.Logf("TestLog GameDuration: %v", game.GameDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx) * 2) require.NoError(t, wait.ForNextBlock(ctx, l1Client))