From 31e2ecb6fb59775137ef613fd93f1c83826998df Mon Sep 17 00:00:00 2001 From: billxu Date: Tue, 1 Oct 2024 20:53:17 +0800 Subject: [PATCH 1/4] Add MoveN function to the position. --- op-challenger/game/fault/types/position.go | 7 +++ .../game/fault/types/position_test.go | 49 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/op-challenger/game/fault/types/position.go b/op-challenger/game/fault/types/position.go index 86d10730f721..c72e0a187601 100644 --- a/op-challenger/game/fault/types/position.go +++ b/op-challenger/game/fault/types/position.go @@ -154,3 +154,10 @@ func bigMSB(x *big.Int) Depth { } return Depth(x.BitLen() - 1) } + +func (p Position) MoveN(depth uint64, branch uint64) Position { + return Position{ + depth: p.depth + Depth(depth), + indexAtDepth: new(big.Int).Add(p.IndexAtDepth(), new(big.Int).Lsh(big.NewInt(int64(branch)), uint(depth))), + } +} diff --git a/op-challenger/game/fault/types/position_test.go b/op-challenger/game/fault/types/position_test.go index 535c01a7e6bf..f74ac085c10a 100644 --- a/op-challenger/game/fault/types/position_test.go +++ b/op-challenger/game/fault/types/position_test.go @@ -314,3 +314,52 @@ func TestRelativeMoves(t *testing.T) { }) } } + +func TestMoveN(t *testing.T) { + tests0 := []struct { + startGIndex *big.Int + defendGIndex *big.Int + }{ + {bi(1), bi(4)}, + {bi(2), bi(8)}, + {bi(4), bi(16)}, + } + depth := uint64(2) + branch := uint64(0) + for _, test := range tests0 { + pos := NewPositionFromGIndex(test.startGIndex) + result := pos.MoveN(depth, branch) + require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) + } + + tests1 := []struct { + startGIndex *big.Int + defendGIndex *big.Int + }{ + {bi(2), bi(12)}, + {bi(4), bi(20)}, + {bi(8), bi(36)}, + } + depth = uint64(2) + branch = uint64(1) + for _, test := range tests1 { + pos := NewPositionFromGIndex(test.startGIndex) + result := pos.MoveN(depth, branch) + require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) + } + + tests3 := []struct { + startGIndex *big.Int + defendGIndex *big.Int + }{ + {bi(4), bi(28)}, + {bi(8), bi(44)}, + } + depth = uint64(2) + branch = uint64(3) + for _, test := range tests3 { + pos := NewPositionFromGIndex(test.startGIndex) + result := pos.MoveN(depth, branch) + require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) + } +} From 58c43ed41d866fbe5d00bb612d0773015783b53a Mon Sep 17 00:00:00 2001 From: billxu Date: Thu, 3 Oct 2024 00:55:15 +0800 Subject: [PATCH 2/4] Add a constant query function to FaultDisputeGameN, modify the attack branch variable to uint256, to unify with other variable types. --- .../src/dispute/FaultDisputeGameN.sol | 32 ++++++++++++------- .../src/dispute/lib/LibPosition.sol | 2 +- .../test/dispute/FaultDisputeGameNTest.sol | 4 +-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGameN.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGameN.sol index dfc67c9c694e..7a23f8604c47 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGameN.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGameN.sol @@ -263,7 +263,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { function stepV2( uint256 _claimIndex, - uint64 _attackBranch, + uint256 _attackBranch, bytes calldata _stateData, StepProof calldata _proof ) @@ -299,16 +299,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // which is the number of leaves in each execution trace subgame. This is so that we can // determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`. // Determine the position of the step. - Position stepPos = parentPos.moveN(N_BITS, _attackBranch); + Position stepPos = parentPos.moveN(N_BITS, uint128(_attackBranch)); if (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH)) == 0) { preStateClaim = ABSOLUTE_PRESTATE; } else { (preStateClaim, preStatePos) = _findTraceAncestorV2( - Position.wrap(parentPos.raw() - 1 + _attackBranch), claimIndex, false, _proof.preStateItem + Position.wrap(parentPos.raw() - 1 + uint128(_attackBranch)), claimIndex, false, _proof.preStateItem ); } // For all attacks, the poststate is the parent claim. - postStatePos = Position.wrap(parent.position.raw() + _attackBranch); + postStatePos = Position.wrap(parent.position.raw() + uint128(_attackBranch)); postStateClaim = getClaim(parent.claim.raw(), postStatePos, _proof.postStateItem); } else { uint256 claimIndex = _claimIndex; @@ -316,10 +316,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // If the step is a defense, the poststate exists elsewhere in the game state, // and the parent claim is the expected pre-state. - preStatePos = Position.wrap(parent.position.raw() + _attackBranch - 1); + preStatePos = Position.wrap(parent.position.raw() + uint128(_attackBranch) - 1); preStateClaim = getClaim(parent.claim.raw(), preStatePos, _proof.preStateItem); (postStateClaim, postStatePos) = - _findExecTraceAncestor(Position.wrap(parentPos.raw() + _attackBranch), claimIndex, _proof.postStateItem); + _findExecTraceAncestor(Position.wrap(parentPos.raw() + uint128(_attackBranch)), claimIndex, _proof.postStateItem); } // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the @@ -355,7 +355,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { parent.counteredBy = msg.sender; } - function moveV2(Claim _disputed, uint256 _challengeIndex, Claim _claim, uint64 _attackBranch) internal { + function moveV2(Claim _disputed, uint256 _challengeIndex, Claim _claim, uint256 _attackBranch) internal { // For N = 4 (bisec), // 1. _attackBranch == 0 (attack) // 2. _attackBranch == 1 (attack) @@ -917,6 +917,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { l2ChainId_ = L2_CHAIN_ID; } + /// @notice Returns n-bits + function nBits() external view returns (uint256 nBits_) { + nBits_ = N_BITS; + } + + /// @notice Returns n-bits + function maxAttackBranch() external view returns (uint256 maxAttackBranch_) { + maxAttackBranch_ = MAX_ATTACK_BRANCH; + } + //////////////////////////////////////////////////////////////// // HELPERS // //////////////////////////////////////////////////////////////// @@ -942,7 +952,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { Claim _rootClaim, uint256 _parentIdx, Position _parentPos, - uint64 _attackBranch + uint256 _attackBranch ) internal view @@ -954,7 +964,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // If the move is a defense, the disputed output could have been made by either party. In this case, we // need to search for the parent output to determine what the expected status byte should be. - Position disputedLeafPos = Position.wrap(_parentPos.raw() + _attackBranch); + Position disputedLeafPos = Position.wrap(_parentPos.raw() + uint128(_attackBranch)); (, Position disputedPos) = _findTraceAncestorRoot({ _pos: disputedLeafPos, _start: _parentIdx, _global: true }); uint8 vmStatus = uint8(_rootClaim.raw()[0]); @@ -1043,7 +1053,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // is the disputed output root. (Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position); // Equation is (outputPos + attackBranch) * (1 << N_BITS) = execRootPos - uint64 attackBranch = uint64(execRootPos.raw() / (1 << N_BITS) - outputPos.raw()); + uint128 attackBranch = uint128(execRootPos.raw() / (1 << N_BITS) - 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 @@ -1192,7 +1202,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { function attackV2( Claim _disputed, uint256 _parentIndex, - uint64 _attackBranch, + uint256 _attackBranch, uint256 _daType, bytes memory _claims ) diff --git a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol index 007255b65232..18b887f82736 100644 --- a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol +++ b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol @@ -193,7 +193,7 @@ library LibPosition { } } - function moveN(Position _position, uint256 _bits, uint64 _branch) internal pure returns (Position move_) { + function moveN(Position _position, uint256 _bits, uint256 _branch) internal pure returns (Position move_) { assembly { move_ := shl(_bits, or(_branch, _position)) } diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGameNTest.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGameNTest.sol index 9d0986765d2d..e654171ed394 100644 --- a/packages/contracts-bedrock/test/dispute/FaultDisputeGameNTest.sol +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGameNTest.sol @@ -37,13 +37,13 @@ contract FaultDisputeGameTest is FaultDisputeGame { // For testing convenience and to minimize changes in the testing code, the submission of the "claims" value is // omitted during the attack. In contract testing, the value of "claims" is already known and does not need to be // submitted via calldata or EIP-4844 during the attack. - function attackV2(Claim _disputed, uint256 _parentIndex, Claim _claim, uint64 _attackBranch) public payable { + function attackV2(Claim _disputed, uint256 _parentIndex, Claim _claim, uint256 _attackBranch) public payable { moveV2(_disputed, _parentIndex, _claim, _attackBranch); } function stepV2( uint256 _claimIndex, - uint64 _attackBranch, + uint256 _attackBranch, bytes calldata _stateData, StepProof calldata _proof ) From c1ae00b4cf3c32180614479c562bda4e2810593e Mon Sep 17 00:00:00 2001 From: billxu Date: Thu, 3 Oct 2024 01:42:38 +0800 Subject: [PATCH 3/4] delete go code --- op-challenger/game/fault/types/position.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/op-challenger/game/fault/types/position.go b/op-challenger/game/fault/types/position.go index c72e0a187601..86d10730f721 100644 --- a/op-challenger/game/fault/types/position.go +++ b/op-challenger/game/fault/types/position.go @@ -154,10 +154,3 @@ func bigMSB(x *big.Int) Depth { } return Depth(x.BitLen() - 1) } - -func (p Position) MoveN(depth uint64, branch uint64) Position { - return Position{ - depth: p.depth + Depth(depth), - indexAtDepth: new(big.Int).Add(p.IndexAtDepth(), new(big.Int).Lsh(big.NewInt(int64(branch)), uint(depth))), - } -} From c485da15f2e99aec07db3bfb4f2b75c3a202b272 Mon Sep 17 00:00:00 2001 From: billxu Date: Thu, 3 Oct 2024 01:43:29 +0800 Subject: [PATCH 4/4] delete go code --- .../game/fault/types/position_test.go | 49 ------------------- 1 file changed, 49 deletions(-) diff --git a/op-challenger/game/fault/types/position_test.go b/op-challenger/game/fault/types/position_test.go index f74ac085c10a..535c01a7e6bf 100644 --- a/op-challenger/game/fault/types/position_test.go +++ b/op-challenger/game/fault/types/position_test.go @@ -314,52 +314,3 @@ func TestRelativeMoves(t *testing.T) { }) } } - -func TestMoveN(t *testing.T) { - tests0 := []struct { - startGIndex *big.Int - defendGIndex *big.Int - }{ - {bi(1), bi(4)}, - {bi(2), bi(8)}, - {bi(4), bi(16)}, - } - depth := uint64(2) - branch := uint64(0) - for _, test := range tests0 { - pos := NewPositionFromGIndex(test.startGIndex) - result := pos.MoveN(depth, branch) - require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) - } - - tests1 := []struct { - startGIndex *big.Int - defendGIndex *big.Int - }{ - {bi(2), bi(12)}, - {bi(4), bi(20)}, - {bi(8), bi(36)}, - } - depth = uint64(2) - branch = uint64(1) - for _, test := range tests1 { - pos := NewPositionFromGIndex(test.startGIndex) - result := pos.MoveN(depth, branch) - require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) - } - - tests3 := []struct { - startGIndex *big.Int - defendGIndex *big.Int - }{ - {bi(4), bi(28)}, - {bi(8), bi(44)}, - } - depth = uint64(2) - branch = uint64(3) - for _, test := range tests3 { - pos := NewPositionFromGIndex(test.startGIndex) - result := pos.MoveN(depth, branch) - require.Equalf(t, test.defendGIndex, result.ToGIndex(), "move GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) - } -}