Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AnchorStateRegistry Implementation to OPSM #11955

Merged
merged 24 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
eb6560f
feat: Add ASR proxy to OPStackManager
maurelian Sep 17, 2024
ef6b6dd
feat: Add AnchorStateRegistry blueprint
maurelian Sep 17, 2024
733b7b8
feat: Add AnchorStateRegistry Implementation
maurelian Sep 17, 2024
b187867
feat: Return startingAnchorInputs as bytes
maurelian Sep 19, 2024
ee06b3a
rebuild snapshots
maurelian Sep 19, 2024
98c5c10
Merge branch 'develop' into opsm/fpac-asr-imp
maurelian Sep 19, 2024
b40bb4a
fix: ASR initializer encoding
maurelian Sep 19, 2024
8c23598
Merge branch 'develop' into opsm/fpac-asr-imp
maurelian Sep 19, 2024
56b3e61
handoff commit with op-deployer debugging
maurelian Sep 19, 2024
8a5b142
test and golang fixes
mslipper Sep 19, 2024
a5bafe7
hardcode permissioned state
mslipper Sep 19, 2024
524a0e4
hardcode 0xdead as the starting anchor root
mds1 Sep 20, 2024
e2c74b2
Merge branch 'develop' into opsm/fpac-asr-imp
mds1 Sep 20, 2024
5330787
chore: fix semver lock
mds1 Sep 20, 2024
c78530f
fix: no permissionless root, remove hash from 0xdead
mds1 Sep 20, 2024
ca8be30
fix: use 0xdead root properly
mds1 Sep 20, 2024
5eabd37
fix: set the override in the input contract
mds1 Sep 20, 2024
b81a774
Merge branch 'develop' into opsm/fpac-asr-imp
mds1 Sep 20, 2024
68e99d4
Merge remote-tracking branch 'upstream/develop' into opsm/fpac-asr-imp
mslipper Sep 22, 2024
d49f363
Fix tests and accidental mutation of `Implementation` struct
mslipper Sep 23, 2024
b8be291
lint
mslipper Sep 23, 2024
517f553
semver
mslipper Sep 23, 2024
14a21d2
Update op-chain-ops/deployer/opsm/opchain.go
mds1 Sep 23, 2024
f9cf4fa
Update packages/contracts-bedrock/scripts/DeployOPChain.s.sol
mds1 Sep 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions op-chain-ops/deployer/opsm/opchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ type DeployOPChainInput struct {
Proposer common.Address
Challenger common.Address

BasefeeScalar uint32
BlobBaseFeeScalar uint32
L2ChainId *big.Int
OpsmProxy common.Address
BasefeeScalar uint32
BlobBaseFeeScalar uint32
L2ChainId *big.Int
StartingAnchorRoots []byte
OpsmProxy common.Address
}

func (input *DeployOPChainInput) InputSet() bool {
Expand Down Expand Up @@ -65,13 +66,15 @@ func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOu
return dco, fmt.Errorf("failed to insert DeployOPChainInput precompile: %w", err)
}
defer cleanupInput()
host.Label(inputAddr, "DeployOPChainInput")

cleanupOutput, err := script.WithPrecompileAtAddress[*DeployOPChainOutput](host, outputAddr, &dco,
script.WithFieldSetter[*DeployOPChainOutput])
if err != nil {
return dco, fmt.Errorf("failed to insert DeployOPChainOutput precompile: %w", err)
}
defer cleanupOutput()
host.Label(outputAddr, "DeployOPChainOutput")

deployScript, cleanupDeploy, err := script.WithScript[DeployOPChainScript](host, "DeployOPChain.s.sol", "DeployOPChain")
if err != nil {
Expand Down
28 changes: 28 additions & 0 deletions op-chain-ops/deployer/pipeline/opchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,33 @@ import (
"github.com/ethereum/go-ethereum/common"
)

// PermissionedGameStartingAnchorRoots is an empty anchor root generated by the
// console.log in DeployOpChain.t.sol
var PermissionedGameStartingAnchorRoots = []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc3, 0x02, 0x67, 0xa0, 0x00, 0xa3, 0xd0, 0x25, 0x7a, 0x64, 0x83, 0xe4,
0x1d, 0x64, 0x97, 0xa4, 0x80, 0xa7, 0x83, 0x96, 0x35, 0xc8, 0x19, 0x34,
0x00, 0x82, 0xcf, 0xe3, 0xe0, 0xda, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x4e, 0x03, 0x3a, 0x37, 0x25, 0xd1, 0x5c, 0x61, 0x74, 0xf8, 0x6f, 0x0c,
0xdd, 0x21, 0x0c, 0x84, 0x9a, 0x3f, 0xbd, 0xcb, 0x88, 0xaa, 0x68, 0x2b,
0xf5, 0x1c, 0x61, 0x4b, 0x1e, 0x89, 0x5c, 0x4f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xf4,
}

func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *state.State, chainID common.Hash) error {
lgr := env.Logger.New("stage", "deploy-opchain")

Expand Down Expand Up @@ -62,6 +89,7 @@ func DeployOPChain(ctx context.Context, env *Env, intent *state.Intent, st *stat
BasefeeScalar: 1368,
BlobBaseFeeScalar: 801949,
L2ChainId: chainID.Big(),
StartingAnchorRoots: PermissionedGameStartingAnchorRoots,
OpsmProxy: st.ImplementationsDeployment.OpsmProxyAddress,
},
)
Expand Down
16 changes: 8 additions & 8 deletions packages/contracts-bedrock/scripts/DeployImplementations.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -636,14 +636,14 @@ contract DeployImplementations is Script {
// The fault proofs contracts are configured as follows:
// | Contract | Proxied | Deployment | MCP Ready |
// |-------------------------|---------|-----------------------------------|------------|
// | DisputeGameFactory | Yes | Bespoke | Yes |
// | AnchorStateRegistry | Yes | Bespoke | No |
// | FaultDisputeGame | No | Bespoke | No |
// | PermissionedDisputeGame | No | Bespoke | No |
// | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No |
// | PreimageOracle | No | Shared | N/A |
// | MIPS | No | Shared | N/A |
// | OptimismPortal2 | Yes | Shared | No |
// | DisputeGameFactory | Yes | Bespoke | Yes | X
// | AnchorStateRegistry | Yes | Bespoke | No | WIP
// | FaultDisputeGame | No | Bespoke | No | Todo
// | PermissionedDisputeGame | No | Bespoke | No | Todo
// | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | No | Todo: Proxies.
// | PreimageOracle | No | Shared | N/A | X
// | MIPS | No | Shared | N/A | X
// | OptimismPortal2 | Yes | Shared | No | X
//
// This script only deploys the shared contracts. The bespoke contracts are deployed by
// `DeployOPChain.s.sol`. When the shared contracts are proxied, the contracts deployed here are
Expand Down
17 changes: 16 additions & 1 deletion packages/contracts-bedrock/scripts/DeployOPChain.s.sol
mds1 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ contract DeployOPChainInput is BaseDeployIO {
uint32 internal _blobBaseFeeScalar;
uint256 internal _l2ChainId;
OPStackManager internal _opsmProxy;
bytes internal _startingAnchorRoots;

function set(bytes4 _sel, address _addr) public {
require(_addr != address(0), "DeployOPChainInput: cannot set zero address");
Expand All @@ -70,6 +71,14 @@ contract DeployOPChainInput is BaseDeployIO {
}
}

function set(bytes4 _sel, bytes memory _value) public {
mslipper marked this conversation as resolved.
Show resolved Hide resolved
if (_sel == this.startingAnchorRoots.selector) {
_startingAnchorRoots = _value;
} else {
revert("DeployOPChainInput: unknown selector");
}
}

function loadInputFile(string memory _infile) public pure {
_infile;
require(false, "DeployOPChainInput: not implemented");
Expand Down Expand Up @@ -121,6 +130,11 @@ contract DeployOPChainInput is BaseDeployIO {
return _l2ChainId;
}

function startingAnchorRoots() public view returns (bytes memory) {
maurelian marked this conversation as resolved.
Show resolved Hide resolved
require(_startingAnchorRoots.length > 0, "DeployOPChainInput: not set");
return _startingAnchorRoots;
}

// TODO: Check that opsm is proxied and it has an implementation.
function opsmProxy() public view returns (OPStackManager) {
require(address(_opsmProxy) != address(0), "DeployOPChainInput: not set");
Expand Down Expand Up @@ -430,7 +444,8 @@ contract DeployOPChain is Script {
roles: roles,
basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(),
l2ChainId: _doi.l2ChainId()
l2ChainId: _doi.l2ChainId(),
startingAnchorRoots: _doi.startingAnchorRoots()
});

vm.broadcast(msg.sender);
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649"
},
"src/L1/OPStackManager.sol": {
"initCodeHash": "0x022b3f6a80eb637972dd0d9ce8666a037c4b916889f44f86771d8c3add9d615d",
"sourceCodeHash": "0xb085725e18c1a0cc1826b770e403ecad765fce686bb80555bf0f6c3c67b21cba"
"initCodeHash": "0xf624ceae7a4ea10238f63a545dc66a109e84ea5a29a5cc9b682f056e2de7ed93",
"sourceCodeHash": "0x7c4d8311b71759a36651cc3b2daa742571c822f54cfbaa4cdc1d48f5f684d27c"
},
"src/L1/OptimismPortal.sol": {
"initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"internalType": "uint256",
"name": "l2ChainId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "startingAnchorRoots",
"type": "bytes"
}
],
"internalType": "struct OPStackManager.DeployInput",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"internalType": "uint256",
"name": "l2ChainId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "startingAnchorRoots",
"type": "bytes"
}
],
"internalType": "struct OPStackManager.DeployInput",
Expand Down
26 changes: 24 additions & 2 deletions packages/contracts-bedrock/src/L1/OPStackManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ contract OPStackManager is ISemver, Initializable {
uint32 basefeeScalar;
uint32 blobBasefeeScalar;
uint256 l2ChainId;
// The correct type is AnchorStateRegistry.StartingAnchorRoot[] memory,
// but OP Deployer does not yet support structs.
bytes startingAnchorRoots;
maurelian marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice The full set of outputs from deploying a new OP Stack chain.
Expand Down Expand Up @@ -206,8 +209,6 @@ contract OPStackManager is ISemver, Initializable {
// -------- TODO: Placeholders --------
// For contracts we don't yet deploy, we set the outputs to dummy proxies so they have code to pass assertions.
// We do these first, that way the disputeGameFactoryProxy is set when passed to the SystemConfig input.
output.anchorStateRegistryProxy = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "3"));
output.anchorStateRegistryImpl = AnchorStateRegistry(deployProxy(l2ChainId, output.opChainProxyAdmin, "4"));
output.faultDisputeGame = FaultDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "5"));
output.permissionedDisputeGame = PermissionedDisputeGame(deployProxy(l2ChainId, output.opChainProxyAdmin, "6"));
output.delayedWETHPermissionedGameProxy =
Expand Down Expand Up @@ -293,10 +294,16 @@ contract OPStackManager is ISemver, Initializable {
data = encodeL1StandardBridgeInitializer(impl.initializer, output);
upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data);

// TODO: also call setImplementation() once the dispute games are deployed.
impl = getLatestImplementation("DisputeGameFactory");
data = encodeDisputeGameFactoryInitializer(impl.initializer, _input);
upgradeAndCall(output.opChainProxyAdmin, address(output.disputeGameFactoryProxy), impl.logic, data);

impl.logic = address(output.anchorStateRegistryImpl);
impl.initializer = AnchorStateRegistry.initialize.selector;
data = encodeAnchorStateRegistryInitializer(impl.initializer, _input);
upgradeAndCall(output.opChainProxyAdmin, address(output.anchorStateRegistryProxy), impl.logic, data);

// -------- Finalize Deployment --------
// Transfer ownership of the ProxyAdmin from this contract to the specified owner.
output.opChainProxyAdmin.transferOwnership(_input.roles.opChainProxyAdminOwner);
Expand Down Expand Up @@ -464,6 +471,21 @@ contract OPStackManager is ISemver, Initializable {
return abi.encodeWithSelector(_selector, _input.roles.opChainProxyAdminOwner);
}

function encodeAnchorStateRegistryInitializer(
bytes4 _selector,
DeployInput memory _input
)
internal
view
virtual
returns (bytes memory)
maurelian marked this conversation as resolved.
Show resolved Hide resolved
{
// this line fails in the op-deployer tests because it is not passing in any data
AnchorStateRegistry.StartingAnchorRoot[] memory startingAnchorRoots =
abi.decode(_input.startingAnchorRoots, (AnchorStateRegistry.StartingAnchorRoot[]));
return abi.encodeWithSelector(_selector, startingAnchorRoots, superchainConfig);
}

/// @notice Returns default, standard config arguments for the SystemConfig initializer.
/// This is used by subclasses to reduce code duplication.
function defaultSystemConfigParams(
Expand Down
51 changes: 49 additions & 2 deletions packages/contracts-bedrock/test/DeployOPChain.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";

import { GameType, GameTypes, Hash, OutputRoot } from "src/dispute/lib/Types.sol";

import { console2 as console } from "forge-std/console2.sol";

contract DeployOPChainInput_Test is Test {
DeployOPChainInput doi;

Expand Down Expand Up @@ -336,9 +340,32 @@ contract DeployOPChain_TestBase is Test {
uint32 basefeeScalar = 100;
uint32 blobBaseFeeScalar = 200;
uint256 l2ChainId = 300;
AnchorStateRegistry.StartingAnchorRoot[] startingAnchorRoots;
OPStackManager opsm = OPStackManager(address(0));

function setUp() public virtual {
// Set defaults for reference types
uint256 cannonBlock = 400;
uint256 permissionedBlock = 500;
startingAnchorRoots.push(
AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({ root: Hash.wrap(keccak256("defaultOutputRootCannon")), l2BlockNumber: cannonBlock })
})
);
startingAnchorRoots.push(
AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(keccak256("defaultOutputRootPermissioned")),
l2BlockNumber: permissionedBlock
})
})
);

// The output of this line was used to generate the bytes string that I have hardcoded into apply_test.go
console.logBytes(abi.encode(startingAnchorRoots));

// Initialize deploy scripts.
DeploySuperchain deploySuperchain = new DeploySuperchain();
(DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts();
Expand Down Expand Up @@ -389,7 +416,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
return keccak256(abi.encode(_seed, _i));
}

function testFuzz_run_memory_succeeds(bytes32 _seed) public {
function testFuzz_run_memory_succeed(bytes32 _seed) public {
opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0))));
systemConfigOwner = address(uint160(uint256(hash(_seed, 1))));
batcher = address(uint160(uint256(hash(_seed, 2))));
Expand All @@ -398,7 +425,26 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
challenger = address(uint160(uint256(hash(_seed, 5))));
basefeeScalar = uint32(uint256(hash(_seed, 6)));
blobBaseFeeScalar = uint32(uint256(hash(_seed, 7)));
l2ChainId = uint256(uint256(hash(_seed, 8)));
l2ChainId = uint256(hash(_seed, 8));

// Set the initial anchor states. The typical usage we expect is to pass in one root per game type.
uint256 cannonBlock = uint256(hash(_seed, 9));
uint256 permissionedBlock = uint256(hash(_seed, 10));
startingAnchorRoots.push(
AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({ root: Hash.wrap(keccak256(abi.encode(_seed, 11))), l2BlockNumber: cannonBlock })
})
);
startingAnchorRoots.push(
AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(keccak256(abi.encode(_seed, 12))),
l2BlockNumber: permissionedBlock
})
})
);

doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
Expand All @@ -410,6 +456,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opsmProxy.selector, address(opsm)); // Not fuzzed since it must be an actual instance.
doi.set(doi.startingAnchorRoots.selector, abi.encode(startingAnchorRoots));

deployOPChain.run(doi, doo);

Expand Down
4 changes: 3 additions & 1 deletion packages/contracts-bedrock/test/L1/OPStackManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase {
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opsmProxy.selector, address(opsm));
doi.set(doi.startingAnchorRoots.selector, abi.encode(startingAnchorRoots));
}

// This helper function is used to convert the input struct type defined in DeployOPChain.s.sol
Expand All @@ -62,7 +63,8 @@ contract OPStackManager_Deploy_Test is DeployOPChain_TestBase {
}),
basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(),
l2ChainId: _doi.l2ChainId()
l2ChainId: _doi.l2ChainId(),
startingAnchorRoots: _doi.startingAnchorRoots()
});
}

Expand Down