Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor_derivation
Browse files Browse the repository at this point in the history
# Conflicts:
#	bindings/bin/rollup_deployed.hex
#	bindings/bindings/rollup.go
#	bindings/bindings/rollup_more.go
#	node/derivation/derivation.go
#	oracle/oracle/batch.go
  • Loading branch information
curryxbo committed Dec 26, 2024
2 parents 6d63e23 + fc22179 commit 8dafffe
Show file tree
Hide file tree
Showing 54 changed files with 889 additions and 1,315 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prover/
16 changes: 16 additions & 0 deletions MakefileEc2.mk
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,19 @@ build-bk-prod-morph-prod-testnet-to-morph-tx-submitter-holesky:
cp tx-submitter/tx-submitter dist/
tar -czvf tx-submitter.tar.gz dist
aws s3 cp tx-submitter.tar.gz s3://morph-0582-morph-technical-department-testnet-data/testnet/holesky/morph-setup/tx-submitter.tar.gz


build-bk-test-morph-test-qanet-to-morph-node-qanet:
if [ ! -d dist ]; then mkdir -p dist; fi
cd $(PWD)/node && make build
cp node/build/bin/morphnode dist/
cp node/build/bin/tendermint dist/
tar -czvf morph-node.tar.gz dist
aws s3 cp morph-node.tar.gz s3://morph-7637-morph-technical-department-qanet-data/morph-setup/morph-node.tar.gz

build-bk-test-morph-test-qanet-to-morph-tx-submitter-qanet:
if [ ! -d dist ]; then mkdir -p dist; fi
env GO111MODULE=on CGO_LDFLAGS="-ldl" CGO_ENABLED=1 go build -v $(LDFLAGS) -o tx-submitter/tx-submitter ./tx-submitter/cmd
cp tx-submitter/tx-submitter dist/
tar -czvf tx-submitter.tar.gz dist
aws s3 cp tx-submitter.tar.gz s3://morph-7637-morph-technical-department-qanet-data/morph-setup/tx-submitter.tar.gz
2 changes: 1 addition & 1 deletion bindings/bin/l1crossdomainmessenger_deployed.hex

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/bin/l1messagequeuewithgaspriceoracle_deployed.hex

Large diffs are not rendered by default.

231 changes: 33 additions & 198 deletions bindings/bindings/l1crossdomainmessenger.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions bindings/bindings/l1crossdomainmessenger_more.go

Large diffs are not rendered by default.

190 changes: 2 additions & 188 deletions bindings/bindings/l1messagequeuewithgaspriceoracle.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions bindings/bindings/l1messagequeuewithgaspriceoracle_more.go

Large diffs are not rendered by default.

12 changes: 0 additions & 12 deletions contracts/contracts/l1/IL1CrossDomainMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ interface IL1CrossDomainMessenger is ICrossDomainMessenger {
bytes message
);

/// @notice Emitted when have message dropped.
/// @param nonce The index of the message to be dropped.
event DropMessage(uint256 indexed nonce);

/*****************************
* Public Mutating Functions *
*****************************/
Expand Down Expand Up @@ -80,12 +76,4 @@ interface IL1CrossDomainMessenger is ICrossDomainMessenger {
uint32 newGasLimit,
address refundAddress
) external payable;

/// @notice Drop a skipped message.
/// @param from The address of the sender of the message.
/// @param to The address of the recipient of the message.
/// @param value The msg.value passed to the message call.
/// @param messageNonce The nonce for the message to drop.
/// @param message The content of the message.
function dropMessage(address from, address to, uint256 value, uint256 messageNonce, bytes memory message) external;
}
59 changes: 2 additions & 57 deletions contracts/contracts/l1/L1CrossDomainMessenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract L1CrossDomainMessenger is IL1CrossDomainMessenger, CrossDomainMessenger
mapping(bytes32 => uint256) public messageSendTimestamp;

/// @notice Mapping from L1 message hash to drop status.
mapping(bytes32 => bool) public isL1MessageDropped;
mapping(bytes32 => bool) public __isL1MessageDropped;

/// @notice The address of Rollup contract.
address public rollup;
Expand Down Expand Up @@ -192,7 +192,7 @@ contract L1CrossDomainMessenger is IL1CrossDomainMessenger, CrossDomainMessenger

require(messageSendTimestamp[_xDomainCalldataHash] > 0, "Provided message has not been enqueued");
// cannot replay dropped message
require(!isL1MessageDropped[_xDomainCalldataHash], "Message already dropped");
require(!__isL1MessageDropped[_xDomainCalldataHash], "Message already dropped");

// compute and deduct the messaging fee to fee vault.
uint256 _fee = IL1MessageQueue(_messageQueue).estimateCrossDomainMessageFee(_from, _newGasLimit);
Expand Down Expand Up @@ -243,61 +243,6 @@ contract L1CrossDomainMessenger is IL1CrossDomainMessenger, CrossDomainMessenger
}
}

/// @inheritdoc IL1CrossDomainMessenger
function dropMessage(
address _from,
address _to,
uint256 _value,
uint256 _messageNonce,
bytes memory _message
) external override whenNotPaused notInExecution {
// The criteria for dropping a message:
// 1. The message is a L1 message.
// 2. The message has not been dropped before.
// 3. the message and all of its replacement are finalized in L1.
// 4. the message and all of its replacement are skipped.
//
// Possible denial of service attack:
// + replayMessage is called every time someone want to drop the message.
// + replayMessage is called so many times for a skipped message, thus results a long list.
//
// We limit the number of `replayMessage` calls of each message, which may solve the above problem.

address _messageQueue = messageQueue;

// check message exists
bytes memory _xDomainCalldata = _encodeXDomainCalldata(_from, _to, _value, _messageNonce, _message);
bytes32 _xDomainCalldataHash = keccak256(_xDomainCalldata);
require(messageSendTimestamp[_xDomainCalldataHash] > 0, "Provided message has not been enqueued");

// check message not dropped
require(!isL1MessageDropped[_xDomainCalldataHash], "Message already dropped");

// check message is finalized
uint256 _lastIndex = replayStates[_xDomainCalldataHash].lastIndex;
if (_lastIndex == 0) _lastIndex = _messageNonce;

// check message is skipped and drop it.
// @note If the list is very long, the message may never be dropped.
while (true) {
IL1MessageQueue(_messageQueue).dropCrossDomainMessage(_lastIndex);
_lastIndex = prevReplayIndex[_lastIndex];
if (_lastIndex == 0) break;
unchecked {
_lastIndex = _lastIndex - 1;
}
}

isL1MessageDropped[_xDomainCalldataHash] = true;
emit DropMessage(_messageNonce);

// set execution context
xDomainMessageSender = Constants.DROP_XDOMAIN_MESSAGE_SENDER;
IMessageDropCallback(_from).onDropMessage{value: _value}(_message);
// clear execution context
xDomainMessageSender = Constants.DEFAULT_XDOMAIN_MESSAGE_SENDER;
}

/************************
* Restricted Functions *
************************/
Expand Down
11 changes: 0 additions & 11 deletions contracts/contracts/l1/rollup/IL1MessageQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ interface IL1MessageQueue {
/// @param count The number of messages popped.
event DequeueTransaction(uint256 startIndex, uint256 count);

/// @notice Emitted when a message is dropped from L1.
/// @param index The index of message dropped.
event DropTransaction(uint256 index);

/// @notice Emitted when owner updates gas oracle contract.
/// @param _oldGasOracle The address of old gas oracle contract.
/// @param _newGasOracle The address of new gas oracle contract.
Expand Down Expand Up @@ -95,10 +91,6 @@ interface IL1MessageQueue {
bytes calldata data
) external view returns (bytes32);

/// @notice Return whether the message is dropped.
/// @param queueIndex The queue index of the message to check.
function isMessageDropped(uint256 queueIndex) external view returns (bool);

/*****************************
* Public Mutating Functions *
*****************************/
Expand Down Expand Up @@ -132,7 +124,4 @@ interface IL1MessageQueue {
/// @param startIndex The start index to pop.
/// @param count The number of messages to pop.
function popCrossDomainMessage(uint256 startIndex, uint256 count) external;

/// @notice Drop a skipped message from the queue.
function dropCrossDomainMessage(uint256 index) external;
}
19 changes: 2 additions & 17 deletions contracts/contracts/l1/rollup/L1MessageQueueWithGasPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
/// @notice The max gas limit of L1 transactions.
uint256 public maxGasLimit;

/// @dev The bitmap for dropped messages, where `droppedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`.
BitMapsUpgradeable.BitMap private droppedMessageBitmap;
/// @dev The bitmap for dropped messages, where `droppedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`. Deprecated.
BitMapsUpgradeable.BitMap private __droppedMessageBitmap;

/// @dev The bitmap for skipped messages, where `skippedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`. Deprecated.
mapping(uint256 => uint256) private __skippedMessageBitmap;
Expand Down Expand Up @@ -260,11 +260,6 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
return hash;
}

/// @inheritdoc IL1MessageQueue
function isMessageDropped(uint256 _queueIndex) external view returns (bool) {
return droppedMessageBitmap.get(_queueIndex);
}

/*****************************
* Public Mutating Functions *
*****************************/
Expand Down Expand Up @@ -325,16 +320,6 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
emit DequeueTransaction(_startIndex, _count);
}

/// @inheritdoc IL1MessageQueue
function dropCrossDomainMessage(uint256 _index) external onlyMessenger {
require(_index < pendingQueueIndex, "cannot drop pending message");

require(!droppedMessageBitmap.get(_index), "message already dropped");
droppedMessageBitmap.set(_index);

emit DropTransaction(_index);
}

/************************
* Restricted Functions *
************************/
Expand Down
65 changes: 0 additions & 65 deletions contracts/contracts/test/L1CrossDomainMessenger.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -427,69 +427,6 @@ contract L1CrossDomainMessengerTest is L1GatewayBaseTest {
assertEq(nonce + 2, l1CrossDomainMessenger.messageNonce());
}

function test_dropMessage_notEnqueued_reverts() external {
address sender = address(this);
address to = address(bob);
bytes memory data = "send message";
// hevm.deal(sender, 10 ether);

// send value zero
uint256 value = 0;
uint256 nonce = l1MessageQueueWithGasPriceOracle.nextCrossDomainMessageIndex();

// Expect revert when the message has not been enqueued.
hevm.expectRevert("Provided message has not been enqueued");
l1CrossDomainMessenger.dropMessage(sender, to, value, nonce, data);
}

function test_dropMessage_succeeds(uint256 amount, address recipient, bytes memory dataToCall) public {
amount = bound(amount, 1, address(this).balance);
bytes memory message = abi.encodeCall(
IL2ETHGateway.finalizeDepositETH,
(address(this), recipient, amount, dataToCall)
);

l1ETHGateway.depositETHAndCall{value: amount}(recipient, amount, dataToCall, defaultGasLimit);

// pop message 0
hevm.startPrank(address(rollup));
l1MessageQueueWithGasPriceOracle.popCrossDomainMessage(0, 1);
assertEq(l1MessageQueueWithGasPriceOracle.pendingQueueIndex(), 1);
hevm.stopPrank();

// Drop message 0 and verify balance
revertOnReceive = false;
uint256 balance = address(this).balance;
l1CrossDomainMessenger.dropMessage(address(l1ETHGateway), address(counterpartGateway), amount, 0, message);
assertEq(balance + amount, address(this).balance);
}

function test_dropMessage_dropAgain_reverts(uint256 amount, address recipient, bytes memory dataToCall) public {
amount = bound(amount, 1, address(this).balance);
bytes memory message = abi.encodeCall(
IL2ETHGateway.finalizeDepositETH,
(address(this), recipient, amount, dataToCall)
);

l1ETHGateway.depositETHAndCall{value: amount}(recipient, amount, dataToCall, defaultGasLimit);

// pop message 0
hevm.startPrank(address(rollup));
l1MessageQueueWithGasPriceOracle.popCrossDomainMessage(0, 1);
assertEq(l1MessageQueueWithGasPriceOracle.pendingQueueIndex(), 1);
hevm.stopPrank();

// Drop message 0 and verify balance
revertOnReceive = false;
uint256 balance = address(this).balance;
l1CrossDomainMessenger.dropMessage(address(l1ETHGateway), address(counterpartGateway), amount, 0, message);
assertEq(balance + amount, address(this).balance);

// Expect revert when trying to drop the same message again.
hevm.expectRevert("Message already dropped");
l1CrossDomainMessenger.dropMessage(address(l1ETHGateway), address(counterpartGateway), amount, 0, message);
}

function test_updateMaxReplayTimes_succeeds(uint256 _maxReplayTimes) external {
hevm.assume(_maxReplayTimes > 0);
// not owner, revert
Expand Down Expand Up @@ -529,8 +466,6 @@ contract L1CrossDomainMessengerTest is L1GatewayBaseTest {
l1CrossDomainMessenger.proveAndRelayMessage(address(0), address(0), 0, 0, new bytes(0), wdProof, wdRoot);
hevm.expectRevert("Pausable: paused");
l1CrossDomainMessenger.replayMessage(address(0), address(0), 0, 0, new bytes(0), 0, address(0));
hevm.expectRevert("Pausable: paused");
l1CrossDomainMessenger.dropMessage(address(0), address(0), 0, 0, new bytes(0));

// unpause
hevm.prank(multisig);
Expand Down
25 changes: 0 additions & 25 deletions contracts/contracts/test/L1CustomERC20Gateway.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -182,31 +182,6 @@ contract L1CustomERC20GatewayTest is L1GatewayBaseTest {
_depositERC20WithRecipientAndCalldata(false, amount, recipient, dataToCall, gasLimit, feePerGas);
}

function test_dropMessage_succeeds(uint256 amount, address recipient, bytes memory dataToCall) public {
gateway.updateTokenMapping(address(l1Token), address(l2Token));

amount = bound(amount, 1, l1Token.balanceOf(address(this)));
bytes memory message = abi.encodeCall(
IL2ERC20Gateway.finalizeDepositERC20,
(address(l1Token), address(l2Token), address(this), recipient, amount, dataToCall)
);
gateway.depositERC20AndCall(address(l1Token), recipient, amount, dataToCall, defaultGasLimit);

// pop message 0
hevm.startPrank(address(rollup));
l1MessageQueueWithGasPriceOracle.popCrossDomainMessage(0, 1);
assertEq(l1MessageQueueWithGasPriceOracle.pendingQueueIndex(), 1);
hevm.stopPrank();

// drop message 0
hevm.expectEmit(true, true, false, true);
emit IL1ERC20Gateway.RefundERC20(address(l1Token), address(this), amount);

uint256 balance = l1Token.balanceOf(address(this));
l1CrossDomainMessenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message);
assertEq(balance + amount, l1Token.balanceOf(address(this)));
}

function test_onDropMessage_beforeDropMessage_reverts() public {
uint256 amount = 1000;

Expand Down
64 changes: 0 additions & 64 deletions contracts/contracts/test/L1ERC1155Gateway.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,70 +157,6 @@ contract L1ERC1155GatewayTest is L1GatewayBaseTest, ERC1155TokenReceiver {
_testBatchDepositERC1155WithRecipient(tokenCount, amount, recipient, gasLimit, feePerGas);
}

function test_dropMessage_succeeds(uint256 tokenId, uint256 amount) public {
gateway.updateTokenMapping(address(l1Token), address(l2Token));

tokenId = bound(tokenId, 0, TOKEN_COUNT - 1);
amount = bound(amount, 1, MAX_TOKEN_BALANCE);
bytes memory message = abi.encodeCall(
IL2ERC1155Gateway.finalizeDepositERC1155,
(address(l1Token), address(l2Token), address(this), address(this), tokenId, amount)
);
gateway.depositERC1155(address(l1Token), tokenId, amount, defaultGasLimit);

// pop message 0
hevm.startPrank(address(rollup));
l1MessageQueueWithGasPriceOracle.popCrossDomainMessage(0, 1);
assertEq(l1MessageQueueWithGasPriceOracle.pendingQueueIndex(), 1);
hevm.stopPrank();

// drop message 0
hevm.expectEmit(true, true, false, true);
emit IL1ERC1155Gateway.RefundERC1155(address(l1Token), address(this), tokenId, amount);

uint256 balance = l1Token.balanceOf(address(this), tokenId);
l1CrossDomainMessenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message);
assertEq(balance + amount, l1Token.balanceOf(address(this), tokenId));
}

function test_dropMessageBatch_succeeds(uint256 tokenCount, uint256 amount) public {
tokenCount = bound(tokenCount, 1, TOKEN_COUNT);
amount = bound(amount, 1, MAX_TOKEN_BALANCE);
gateway.updateTokenMapping(address(l1Token), address(l2Token));

uint256[] memory _tokenIds = new uint256[](tokenCount);
uint256[] memory _amounts = new uint256[](tokenCount);
for (uint256 i = 0; i < tokenCount; i++) {
_tokenIds[i] = i;
_amounts[i] = amount;
}

bytes memory message = abi.encodeCall(
IL2ERC1155Gateway.finalizeBatchDepositERC1155,
(address(l1Token), address(l2Token), address(this), address(this), _tokenIds, _amounts)
);
gateway.batchDepositERC1155(address(l1Token), _tokenIds, _amounts, defaultGasLimit);

// pop message 0
hevm.startPrank(address(rollup));
l1MessageQueueWithGasPriceOracle.popCrossDomainMessage(0, 1);
assertEq(l1MessageQueueWithGasPriceOracle.pendingQueueIndex(), 1);
hevm.stopPrank();

// drop message 0
hevm.expectEmit(true, true, false, true);
emit IL1ERC1155Gateway.BatchRefundERC1155(address(l1Token), address(this), _tokenIds, _amounts);

uint256[] memory balances = new uint256[](tokenCount);
for (uint256 i = 0; i < tokenCount; i++) {
balances[i] = l1Token.balanceOf(address(this), _tokenIds[i]);
}
l1CrossDomainMessenger.dropMessage(address(gateway), address(counterpartGateway), 0, 0, message);
for (uint256 i = 0; i < tokenCount; i++) {
assertEq(balances[i] + _amounts[i], l1Token.balanceOf(address(this), _tokenIds[i]));
}
}

function test_onDropMessage_revert(uint256 tokenId, uint256 amount) external {
gateway.updateTokenMapping(address(l1Token), address(l2Token));
tokenId = bound(tokenId, 0, TOKEN_COUNT - 1);
Expand Down
Loading

0 comments on commit 8dafffe

Please sign in to comment.