Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"scripts": {
"build": "hardhat compile",
"test": "hardhat --network hardhat test test/contract/*.spec.ts",
"lint:test": "eslint ./test",
"solhint": "solhint -f table src/**/*.sol",
"prettier:solidity": "prettier --write src/**/*.sol",
Expand Down
12 changes: 6 additions & 6 deletions scripts/rollupCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ async function main() {
}
// Call the createRollup function
console.log('Calling createRollup to generate a new rollup ...')
const createRollupTx = await rollupCreator.createRollup(
config.rollupConfig,
config.batchPoster,
config.validators,
maxDataSize
)
const createRollupTx = await rollupCreator.createRollup({
config: config.rollupConfig,
_batchPoster: config.batchPosters,
_validators: config.validators,
maxDataSize,
})
const createRollupReceipt = await createRollupTx.wait()

const rollupCreatedEvent = createRollupReceipt.events?.find(
Expand Down
13 changes: 12 additions & 1 deletion src/bridge/ISequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,18 @@ interface ISequencerInbox is IDelayedMessageProvider {
*/
function setIsSequencer(address addr, bool isSequencer_) external;

/**
* @notice Updates the batch poster manager, the address which has the ability to rotate batch poster keys
* @param newBatchPosterManager The new batch poster manager to be set
*/
function setBatchPosterManager(address newBatchPosterManager) external;

// ---------- initializer ----------

function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external;
function initialize(
IBridge bridge_,
MaxTimeVariation calldata maxTimeVariation_,
address[] calldata batchPosters_,
address batchPosterManager_
) external;
}
28 changes: 24 additions & 4 deletions src/bridge/SequencerInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
DataNotAuthenticated,
AlreadyValidDASKeyset,
NoSuchKeyset,
NotForked
NotForked,
NotBatchPosterManager
} from "../libraries/Error.sol";
import "./IBridge.sol";
import "./IInbox.sol";
Expand Down Expand Up @@ -54,6 +55,7 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
bytes1 public constant DATA_AUTHENTICATED_FLAG = 0x40;

IOwnable public rollup;

mapping(address => bool) public isBatchPoster;
ISequencerInbox.MaxTimeVariation public maxTimeVariation;

Expand All @@ -66,6 +68,10 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox

mapping(address => bool) public isSequencer;

/// @notice The batch poster manager has the ability to change the batch poster addresses
/// This enables the batch poster to do key rotation
address public batchPosterManager;

// On L1 this should be set to 117964: 90% of Geth's 128KB tx size limit, leaving ~13KB for proving
uint256 public immutable maxDataSize;
uint256 internal immutable deployTimeChainId = block.chainid;
Expand All @@ -82,13 +88,19 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox

function initialize(
IBridge bridge_,
ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_
ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_,
address[] calldata batchPosters_,
address batchPosterManager_
) external onlyDelegated {
if (bridge != IBridge(address(0))) revert AlreadyInit();
if (bridge_ == IBridge(address(0))) revert HadZeroInit();
bridge = bridge_;
rollup = bridge_.rollup();
maxTimeVariation = maxTimeVariation_;
for (uint256 i = 0; i < batchPosters_.length; i++) {
isBatchPoster[batchPosters_[i]] = true;
}
batchPosterManager = batchPosterManager_;
}

function getTimeBounds() internal view virtual returns (TimeBounds memory) {
Expand Down Expand Up @@ -447,7 +459,8 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
}

/// @inheritdoc ISequencerInbox
function setIsBatchPoster(address addr, bool isBatchPoster_) external onlyRollupOwner {
function setIsBatchPoster(address addr, bool isBatchPoster_) external {
if (msg.sender != batchPosterManager) revert NotBatchPosterManager(msg.sender);
isBatchPoster[addr] = isBatchPoster_;
emit OwnerFunctionCalled(1);
}
Expand Down Expand Up @@ -483,11 +496,18 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
}

/// @inheritdoc ISequencerInbox
function setIsSequencer(address addr, bool isSequencer_) external onlyRollupOwner {
function setIsSequencer(address addr, bool isSequencer_) external {
if (msg.sender != batchPosterManager) revert NotBatchPosterManager(msg.sender);
isSequencer[addr] = isSequencer_;
emit OwnerFunctionCalled(4);
}

/// @inheritdoc ISequencerInbox
function setBatchPosterManager(address newBatchPosterManager) external onlyRollupOwner {
batchPosterManager = newBatchPosterManager;
emit OwnerFunctionCalled(5);
}

function isValidKeysetHash(bytes32 ksHash) external view returns (bool) {
return dasKeySetInfo[ksHash].isValidKeyset;
}
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/Error.sol
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,6 @@ error AlreadyValidDASKeyset(bytes32);

/// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
error NoSuchKeyset(bytes32);

/// @dev Thrown when the provided address is not the designated batch poster manager
error NotBatchPosterManager(address);
11 changes: 9 additions & 2 deletions src/rollup/BridgeCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ contract BridgeCreator is Ownable {
function createBridge(
address adminProxy,
address rollup,
ISequencerInbox.MaxTimeVariation memory maxTimeVariation
ISequencerInbox.MaxTimeVariation memory maxTimeVariation,
address[] memory batchPosters,
address batchPosterManager
)
external
returns (
Expand Down Expand Up @@ -99,7 +101,12 @@ contract BridgeCreator is Ownable {
}

frame.bridge.initialize(IOwnable(rollup));
frame.sequencerInbox.initialize(IBridge(frame.bridge), maxTimeVariation);
frame.sequencerInbox.initialize(
IBridge(frame.bridge),
maxTimeVariation,
batchPosters,
batchPosterManager
);
frame.inbox.initialize(IBridge(frame.bridge), ISequencerInbox(frame.sequencerInbox));
frame.rollupEventInbox.initialize(IBridge(frame.bridge));
frame.outbox.initialize(IBridge(frame.bridge));
Expand Down
57 changes: 31 additions & 26 deletions src/rollup/RollupCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ contract RollupCreator is Ownable {
);
event TemplatesUpdated();

struct RollupCreatorConfig {
Config config;
//// @dev The address of the batch poster, not used when set to zero address
address[] _batchPosters;
/// @dev The list of validator addresses, not used when set to empty list
address[] _validators;
uint256 maxDataSize;
address batchPosterManager;
}

BridgeCreator public bridgeCreator;
IOneStepProofEntry public osp;
IChallengeManager public challengeManagerTemplate;
Expand Down Expand Up @@ -66,31 +76,29 @@ contract RollupCreator is Ownable {
* @dev - RollupOwner should be the owner of Rollup
* @dev - Bridge should have a single inbox and outbox
* @dev - Validators and batch poster should be set if provided
* @param config The configuration for the rollup
* @param _batchPoster The address of the batch poster, not used when set to zero address
* @param _validators The list of validator addresses, not used when set to empty list
* @param rollupCreatorConfig The configuration for the rollup creator
* @return The address of the newly created rollup
*/
function createRollup(
Config memory config,
address _batchPoster,
address[] memory _validators,
uint256 maxDataSize
) external returns (address) {
function createRollup(RollupCreatorConfig memory rollupCreatorConfig)
external
returns (address)
{
// Make sure the immutable maxDataSize is as expected
require(
maxDataSize == bridgeCreator.sequencerInboxTemplate().maxDataSize(),
rollupCreatorConfig.maxDataSize == bridgeCreator.sequencerInboxTemplate().maxDataSize(),
"SI_MAX_DATA_SIZE_MISMATCH"
);
require(
maxDataSize == bridgeCreator.inboxTemplate().maxDataSize(),
rollupCreatorConfig.maxDataSize == bridgeCreator.inboxTemplate().maxDataSize(),
"I_MAX_DATA_SIZE_MISMATCH"
);

ProxyAdmin proxyAdmin = new ProxyAdmin();

// Create the rollup proxy to figure out the address and initialize it later
RollupProxy rollup = new RollupProxy{salt: keccak256(abi.encode(config))}();
RollupProxy rollup = new RollupProxy{
salt: keccak256(abi.encode(rollupCreatorConfig.config))
}();

(
IBridge bridge,
Expand All @@ -101,7 +109,9 @@ contract RollupCreator is Ownable {
) = bridgeCreator.createBridge(
address(proxyAdmin),
address(rollup),
config.sequencerInboxMaxTimeVariation
rollupCreatorConfig.config.sequencerInboxMaxTimeVariation,
rollupCreatorConfig._batchPosters,
rollupCreatorConfig.batchPosterManager
);

IChallengeManager challengeManager = IChallengeManager(
Expand All @@ -120,14 +130,14 @@ contract RollupCreator is Ownable {
osp
);

proxyAdmin.transferOwnership(config.owner);
proxyAdmin.transferOwnership(rollupCreatorConfig.config.owner);

// initialize the rollup with this contract as owner to set batch poster and validators
// it will transfer the ownership back to the actual owner later
address actualOwner = config.owner;
config.owner = address(this);
address actualOwner = rollupCreatorConfig.config.owner;
rollupCreatorConfig.config.owner = address(this);
rollup.initializeProxy(
config,
rollupCreatorConfig.config,
ContractDependencies({
bridge: bridge,
sequencerInbox: sequencerInbox,
Expand All @@ -142,18 +152,13 @@ contract RollupCreator is Ownable {
})
);

// setting batch poster, if the address provided is not zero address
if (_batchPoster != address(0)) {
sequencerInbox.setIsBatchPoster(_batchPoster, true);
}

// Call setValidator on the newly created rollup contract just if validator set is not empty
if (_validators.length != 0) {
bool[] memory _vals = new bool[](_validators.length);
for (uint256 i = 0; i < _validators.length; i++) {
if (rollupCreatorConfig._validators.length != 0) {
bool[] memory _vals = new bool[](rollupCreatorConfig._validators.length);
for (uint256 i = 0; i < rollupCreatorConfig._validators.length; i++) {
_vals[i] = true;
}
IRollupAdmin(address(rollup)).setValidator(_validators, _vals);
IRollupAdmin(address(rollup)).setValidator(rollupCreatorConfig._validators, _vals);
}

IRollupAdmin(address(rollup)).setOwner(actualOwner);
Expand Down
Loading