Skip to content

Commit

Permalink
Merge pull request #744 from matter-labs/sb-port-kl/sync-layer-reorg
Browse files Browse the repository at this point in the history
Port kl/sync layer reorg
  • Loading branch information
StanislavBreadless authored Aug 27, 2024
2 parents 391fa4d + d273ebf commit 95c501b
Show file tree
Hide file tree
Showing 39 changed files with 424 additions and 440 deletions.
4 changes: 2 additions & 2 deletions da-contracts/contracts/CalldataDA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ abstract contract CalldataDA {

require(_operatorDAInput.length >= BLOB_DATA_OFFSET + 32 * blobsProvided, "invalid blobs hashes");

cloneCalldata(blobsLinearHashes, _operatorDAInput[BLOB_DATA_OFFSET:], blobsProvided);
_cloneCalldata(blobsLinearHashes, _operatorDAInput[BLOB_DATA_OFFSET:], blobsProvided);

uint256 ptr = BLOB_DATA_OFFSET + 32 * blobsProvided;

Expand Down Expand Up @@ -100,7 +100,7 @@ abstract contract CalldataDA {
/// @param _dst The destination array.
/// @param _input The input calldata.
/// @param _len The length of the slice in 32-byte words to clone.
function cloneCalldata(bytes32[] memory _dst, bytes calldata _input, uint256 _len) internal pure {
function _cloneCalldata(bytes32[] memory _dst, bytes calldata _input, uint256 _len) internal pure {
assembly {
// The pointer to the allocated memory above. We skip 32 bytes to avoid overwriting the length.
let dstPtr := add(_dst, 0x20)
Expand Down
4 changes: 0 additions & 4 deletions da-contracts/contracts/ValidiumL1DAValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,4 @@ contract ValidiumL1DAValidator is IL1DAValidator {
// The rest of the fields that relate to blobs are empty.
output.stateDiffHash = stateDiffHash;
}

function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
return (interfaceId == this.supportsInterface.selector) || (interfaceId == type(IL1DAValidator).interfaceId);
}
}
1 change: 0 additions & 1 deletion l1-contracts/contracts/bridge/L1AssetRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,6 @@ contract L1AssetRouter is
(assetId, transferData) = _checkWithdrawal(_chainId, messageParams, _message, _merkleProof);
}
address l1AssetHandler = assetHandlerAddress[assetId];
// slither-disable-next-line unused-return
IL1AssetHandler(l1AssetHandler).bridgeMint(_chainId, assetId, transferData);
(amount, l1Receiver) = abi.decode(transferData, (uint256, address));

Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/contracts/bridge/L1NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ contract L1NativeTokenVault is IL1NativeTokenVault, Ownable2StepUpgradeable, Pau
uint256 _chainId,
bytes32 _assetId,
bytes calldata _data
) external payable override onlyBridge whenNotPaused returns (address l1Receiver) {
) external payable override onlyBridge whenNotPaused {
// here we are minting the tokens after the bridgeBurn has happened on an L2, so we can assume the l1Token is not zero
address l1Token = tokenAddress[_assetId];
uint256 amount;
address l1Receiver;
(amount, l1Receiver) = abi.decode(_data, (uint256, address));
// Check that the chain has sufficient balance
require(chainBalance[_chainId][l1Token] >= amount, "NTV: not enough funds"); // not enough funds
Expand Down
6 changes: 1 addition & 5 deletions l1-contracts/contracts/bridge/interfaces/IL1AssetHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ interface IL1AssetHandler {
/// @param _chainId the chainId that the message is from
/// @param _assetId the assetId of the asset being bridged
/// @param _data the actual data specified for the function
function bridgeMint(
uint256 _chainId,
bytes32 _assetId,
bytes calldata _data
) external payable returns (address l1Receiver);
function bridgeMint(uint256 _chainId, bytes32 _assetId, bytes calldata _data) external payable;

/// @param _chainId the chainId that the message will be sent to
/// @param _l2Value the msg.value of the L2 transaction
Expand Down
14 changes: 10 additions & 4 deletions l1-contracts/contracts/bridgehub/Bridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
function registerSettlementLayer(
uint256 _newSettlementLayerChainId,
bool _isWhitelisted
) external onlyChainSTM(_newSettlementLayerChainId) onlyL1 {
) external onlyOwner onlyL1 {
whitelistedSettlementLayers[_newSettlementLayerChainId] = _isWhitelisted;
emit SettlementLayerRegistered(_newSettlementLayerChainId, _isWhitelisted);
}
Expand All @@ -266,6 +266,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
address sender = L1_CHAIN_ID == block.chainid ? msg.sender : AddressAliasHelper.undoL1ToL2Alias(msg.sender);
// This method can be accessed by STMDeployer only
require(sender == address(stmDeployer), "BH: not stm deployer");
require(stateTransitionManagerIsRegistered[_assetAddress], "STM not registered");

bytes32 assetInfo = keccak256(abi.encode(L1_CHAIN_ID, sender, _additionalData));
stmAssetIdToAddress[assetInfo] = _assetAddress;
Expand Down Expand Up @@ -336,7 +337,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
Getters
//////////////////////////////////////////////////////////////*/

/// @notice baseToken function, which takes assetId as input, reads assetHandler from AR, and tokenAddress from AH
/// @notice baseToken function, which takes chainId as input, reads assetHandler from AR, and tokenAddress from AH
function baseToken(uint256 _chainId) public view returns (address) {
bytes32 baseTokenAssetId = baseTokenAssetId[_chainId];
IL1BaseTokenAssetHandler assetHandlerAddress = IL1BaseTokenAssetHandler(
Expand Down Expand Up @@ -369,6 +370,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
}

function stmAssetIdFromChainId(uint256 _chainId) public view override returns (bytes32) {
address stmAddress = stateTransitionManager[_chainId];
require(stmAddress != address(0), "chain id not registered");
return stmAssetId(stateTransitionManager[_chainId]);
}

Expand Down Expand Up @@ -636,6 +639,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
_chainData
);
bridgehubMintData = abi.encode(_chainId, stmMintData, chainMintData);

emit MigrationStarted(_chainId, _assetId, _settlementChainId);
}

/// @dev IL1AssetHandler interface, used to receive a chain on the settlement layer.
Expand All @@ -645,7 +650,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
uint256, // originChainId
bytes32 _assetId,
bytes calldata _bridgehubMintData
) external payable override onlyAssetRouter returns (address l1Receiver) {
) external payable override onlyAssetRouter {
(uint256 _chainId, bytes memory _stmData, bytes memory _chainMintData) = abi.decode(
_bridgehubMintData,
(uint256, bytes, bytes)
Expand All @@ -666,7 +671,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
messageRoot.addNewChainIfNeeded(_chainId);
_registerNewHyperchain(_chainId, hyperchain);
IZkSyncHyperchain(hyperchain).forwardedBridgeMint(_chainMintData);
return address(0);

emit MigrationFinalized(_chainId, _assetId, hyperchain);
}

/// @dev IL1AssetHandler interface, used to undo a failed migration of a chain.
Expand Down
12 changes: 12 additions & 0 deletions l1-contracts/contracts/bridgehub/IBridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ interface IBridgehub is IL1AssetHandler {

event SettlementLayerRegistered(uint256 indexed chainId, bool indexed isWhitelisted);

/// @notice Emitted when the bridging to the chain is started.
/// @param chainId Chain ID of the hyperchain
/// @param assetId Asset ID of the token for the hyperchain's STM
/// @param settlementLayerChainId The chain id of the settlement layer the chain migrates to.
event MigrationStarted(uint256 indexed chainId, bytes32 indexed assetId, uint256 indexed settlementLayerChainId);

/// @notice Emitted when the bridging to the chain is complete.
/// @param chainId Chain ID of the hyperchain
/// @param assetId Asset ID of the token for the hyperchain's STM
/// @param hyperchain The address of the hyperchain on the chain where it is migrated to.
event MigrationFinalized(uint256 indexed chainId, bytes32 indexed assetId, address indexed hyperchain);

/// @notice Starts the transfer of admin rights. Only the current admin or owner can propose a new pending one.
/// @notice New admin can accept admin rights by calling `acceptAdmin` function.
/// @param _newPendingAdmin Address of the new admin
Expand Down
15 changes: 12 additions & 3 deletions l1-contracts/contracts/common/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ uint256 constant MAX_NUMBER_OF_HYPERCHAINS = 100;
/// @dev Used as the `msg.sender` for transactions that relayed via a settlement layer.
address constant SETTLEMENT_LAYER_RELAY_SENDER = address(uint160(0x1111111111111111111111111111111111111111));

/// @dev The metadata version that is supported by the ZK Chains to prove that an L2->L1 log was included in a batch.
uint256 constant SUPPORTED_PROOF_METADATA_VERSION = 1;

struct PriorityTreeCommitment {
uint256 nextLeafIndex;
uint256 startIndex;
Expand All @@ -134,11 +137,17 @@ struct HyperchainCommitment {
/// @notice Total number of committed batches i.e. batches[totalBatchesCommitted] points at the latest committed
/// batch
uint256 totalBatchesCommitted;
/// @notice
/// @notice The hash of the L2 system contracts ugpgrade transaction.
/// @dev It is non zero if the migration happens while the upgrade is not yet finalized.
bytes32 l2SystemContractsUpgradeTxHash;
/// @notice
/// @notice The batch when the system contracts upgrade transaction was executed.
/// @dev It is non-zero if the migration happens while the batch where the upgrade tx was present
/// has not been finalized (executed) yet.
uint256 l2SystemContractsUpgradeBatchNumber;
/// @notice The hashes of the batches that are needed to keep the blockchain working.
/// @dev The length of the array is equal to the `totalBatchesCommitted - totalBatchesExecuted + 1`, i.e. we need
/// to store all the unexecuted batches' hashes + 1 latest executed one.
bytes32[] batchHashes;
/// @notice Commitment to the priority merkle tree
/// @notice Commitment to the priority merkle tree.
PriorityTreeCommitment priorityTree;
}
37 changes: 7 additions & 30 deletions l1-contracts/contracts/dev-contracts/test/DummyExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ contract DummyExecutor is IExecutor {
shouldRevertOnExecuteBatches = _shouldRevert;
}

function commitBatches(
function commitBatchesSharedBridge(
uint256,
StoredBatchInfo calldata _lastCommittedBatchData,
CommitBatchInfo[] calldata _newBatchesData
) public {
) external {
require(!shouldRevertOnCommitBatches, "DummyExecutor: shouldRevertOnCommitBatches");
require(
_lastCommittedBatchData.batchNumber == getTotalBatchesCommitted,
Expand All @@ -75,19 +76,12 @@ contract DummyExecutor is IExecutor {
getTotalBatchesCommitted += batchesLength;
}

function commitBatchesSharedBridge(
function proveBatchesSharedBridge(
uint256,
StoredBatchInfo calldata _lastCommittedBatchData,
CommitBatchInfo[] calldata _newBatchesData
) external {
commitBatches(_lastCommittedBatchData, _newBatchesData);
}

function proveBatches(
StoredBatchInfo calldata _prevBatch,
StoredBatchInfo[] calldata _committedBatches,
ProofInput calldata
) public {
ProofInput calldata _proof
) external {
require(!shouldRevertOnProveBatches, "DummyExecutor: shouldRevertOnProveBatches");
require(_prevBatch.batchNumber == getTotalBatchesVerified, "DummyExecutor: Invalid previous batch number");

Expand All @@ -104,15 +98,6 @@ contract DummyExecutor is IExecutor {
);
}

function proveBatchesSharedBridge(
uint256,
StoredBatchInfo calldata _prevBatch,
StoredBatchInfo[] calldata _committedBatches,
ProofInput calldata _proof
) external {
proveBatches(_prevBatch, _committedBatches, _proof);
}

function executeBatches(StoredBatchInfo[] calldata _batchesData) public {
require(!shouldRevertOnExecuteBatches, "DummyExecutor: shouldRevertOnExecuteBatches");
uint256 nBatches = _batchesData.length;
Expand All @@ -126,10 +111,6 @@ contract DummyExecutor is IExecutor {
);
}

function executeBatches(StoredBatchInfo[] calldata _batchesData, PriorityOpsBatchInfo[] calldata) external {
executeBatches(_batchesData);
}

function executeBatchesSharedBridge(uint256, StoredBatchInfo[] calldata _batchesData) external {
executeBatches(_batchesData);
}
Expand All @@ -142,7 +123,7 @@ contract DummyExecutor is IExecutor {
executeBatches(_batchesData);
}

function revertBatches(uint256 _newLastBatch) public {
function revertBatchesSharedBridge(uint256, uint256 _newLastBatch) external {
require(
getTotalBatchesCommitted > _newLastBatch,
"DummyExecutor: The last committed batch is less than new last batch"
Expand All @@ -155,10 +136,6 @@ contract DummyExecutor is IExecutor {
getTotalBatchesCommitted = newTotalBatchesCommitted;
}

function revertBatchesSharedBridge(uint256, uint256 _newLastBatch) external {
revertBatches(_newLastBatch);
}

/// @notice Returns larger of two values
function _maxU256(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? b : a;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
/// @param _chainId the chainId of the chain
/// @param _newLastBatch the new last batch
function revertBatches(uint256 _chainId, uint256 _newLastBatch) external onlyOwnerOrAdmin {
IZkSyncHyperchain(getHyperchain(_chainId)).revertBatches(_newLastBatch);
IZkSyncHyperchain(getHyperchain(_chainId)).revertBatchesSharedBridge(_chainId, _newLastBatch);
}

/// @dev execute predefined upgrade
Expand Down
36 changes: 0 additions & 36 deletions l1-contracts/contracts/state-transition/ValidatorTimelock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,6 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
return committedBatchTimestamp[_chainId].get(_l2BatchNumber);
}

/// @dev Records the timestamp for all provided committed batches and make
/// a call to the hyperchain diamond contract with the same calldata.
function commitBatches(
StoredBatchInfo calldata,
CommitBatchInfo[] calldata _newBatchesData
) external onlyValidator(ERA_CHAIN_ID) {
_commitBatchesInner(ERA_CHAIN_ID, _newBatchesData);
}

/// @dev Records the timestamp for all provided committed batches and make
/// a call to the hyperchain diamond contract with the same calldata.
function commitBatchesSharedBridge(
Expand All @@ -142,31 +133,13 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
_propagateToZkSyncHyperchain(_chainId);
}

/// @dev Make a call to the hyperchain diamond contract with the same calldata.
/// Note: If the batch is reverted, it needs to be committed first before the execution.
/// So it's safe to not override the committed batches.
function revertBatches(uint256) external onlyValidator(ERA_CHAIN_ID) {
_propagateToZkSyncHyperchain(ERA_CHAIN_ID);
}

/// @dev Make a call to the hyperchain diamond contract with the same calldata.
/// Note: If the batch is reverted, it needs to be committed first before the execution.
/// So it's safe to not override the committed batches.
function revertBatchesSharedBridge(uint256 _chainId, uint256) external onlyValidator(_chainId) {
_propagateToZkSyncHyperchain(_chainId);
}

/// @dev Make a call to the hyperchain diamond contract with the same calldata.
/// Note: We don't track the time when batches are proven, since all information about
/// the batch is known on the commit stage and the proved is not finalized (may be reverted).
function proveBatches(
StoredBatchInfo calldata,
StoredBatchInfo[] calldata,
ProofInput calldata
) external onlyValidator(ERA_CHAIN_ID) {
_propagateToZkSyncHyperchain(ERA_CHAIN_ID);
}

/// @dev Make a call to the hyperchain diamond contract with the same calldata.
/// Note: We don't track the time when batches are proven, since all information about
/// the batch is known on the commit stage and the proved is not finalized (may be reverted).
Expand All @@ -179,15 +152,6 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
_propagateToZkSyncHyperchain(_chainId);
}

/// @dev Check that batches were committed at least X time ago and
/// make a call to the hyperchain diamond contract with the same calldata.
function executeBatches(
StoredBatchInfo[] calldata _batchesData,
PriorityOpsBatchInfo[] calldata
) external onlyValidator(ERA_CHAIN_ID) {
_executeBatchesInner(ERA_CHAIN_ID, _batchesData);
}

/// @dev Check that batches were committed at least X time ago and
/// make a call to the hyperchain diamond contract with the same calldata.
function executeBatchesSharedBridge(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,11 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin {
/// @dev It does not check for these addresses to be non-zero, since when migrating to a new settlement
/// layer, we set them to zero.
function _setDAValidatorPair(address _l1DAValidator, address _l2DAValidator) internal {
address oldL1DAValidator = s.l1DAValidator;
address oldL2DAValidator = s.l2DAValidator;
emit NewL1DAValidator(s.l1DAValidator, _l1DAValidator);
emit NewL2DAValidator(s.l2DAValidator, _l2DAValidator);

s.l1DAValidator = _l1DAValidator;
s.l2DAValidator = _l2DAValidator;

emit NewL1DAValidator(oldL1DAValidator, _l1DAValidator);
emit NewL2DAValidator(oldL2DAValidator, _l2DAValidator);
}

/// @inheritdoc IAdmin
Expand Down
Loading

0 comments on commit 95c501b

Please sign in to comment.