Skip to content

Commit

Permalink
One nonce per sender
Browse files Browse the repository at this point in the history
  • Loading branch information
Lohann committed Dec 16, 2024
1 parent c152585 commit 7ff3387
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
13 changes: 4 additions & 9 deletions src/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ contract Gateway is IGateway, IExecutor, IUpgradable, GatewayEIP712 {
mapping(bytes32 => GmpInfo) private _messages;

// Hash of the previous GMP message submitted.
uint256 private _nonce;
mapping(address => uint256) private _nonces;

// Replay protection mechanism, stores the hash of the executed messages
// messageHash => shardId
Expand All @@ -92,13 +92,8 @@ contract Gateway is IGateway, IExecutor, IUpgradable, GatewayEIP712 {
// EIP-712 typed hash
function initialize(address proxyAdmin, TssKey[] calldata keys, Network[] calldata networks) external {
require(PROXY_ADDRESS == address(this) || msg.sender == FACTORY, "only proxy can be initialize");
require(_nonce == 0, "already initialized");
ERC1967.setAdmin(proxyAdmin);

// Initialize the `nonce` as one to avoid the first GMP to spent more gas,
// once initialize the storage cost 21k gas, while alter it cost just 2800 gas.
_nonce = 1;

// Register networks
RouteStore.getMainStorage().initialize(networks, NetworkID.wrap(NETWORK_ID));

Expand All @@ -111,7 +106,7 @@ contract Gateway is IGateway, IExecutor, IUpgradable, GatewayEIP712 {
}

function nonce() external view returns (uint256) {
return _nonce;
return _nonces[msg.sender];
}

function gmpInfo(bytes32 id) external view returns (GmpInfo memory) {
Expand Down Expand Up @@ -301,8 +296,8 @@ contract Gateway is IGateway, IExecutor, IUpgradable, GatewayEIP712 {
// We use 20 bytes for represent the address and 1 bit for the contract flag
GmpSender source = msg.sender.toSender(false);

// Salt is equal to the previous message id (EIP-712 hash), this allows us to establish a sequence and eaily query the message history.
uint256 nextNonce = _nonce++;
// Nonce is per sender, it's incremented for every message sent.
uint256 nextNonce = _nonces[msg.sender]++;

// Create GMP message and update nonce
GmpMessage memory message =
Expand Down
7 changes: 6 additions & 1 deletion src/utils/GasUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ library GasUtils {
/**
* @dev Base cost of the `IGateway.submitMessage` method.
*/
uint256 internal constant SUBMIT_BASE_COST = 23449 + 19;
uint256 internal constant SUBMIT_BASE_COST = 23525;

/**
* @dev Extra gas cost of the first `IGateway.submitMessage` method.
*/
uint256 internal constant FIRST_MESSAGE_EXTRA_COST = 17100;

/**
* @dev Compute the gas cost of memory expansion.
Expand Down
2 changes: 1 addition & 1 deletion test/Example.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ contract ExampleTest is Test {
dest: address(dstToken),
destNetwork: DEST_NETWORK_ID,
gasLimit: 100_000,
salt: 1,
salt: 0,
data: abi.encode(MockERC20.CrossChainTransfer({from: ALICE, to: BOB, amount: 100}))
});

Expand Down
19 changes: 10 additions & 9 deletions test/Gateway.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ contract GatewayBase is Test {

assertEq(
ctx.executionCost,
GasUtils.submitMessageGasCost(uint16(gmp.data.length)) - 4500,
GasUtils.submitMessageGasCost(uint16(gmp.data.length)) - 4500 + 17100,
"unexpected submit message gas cost"
);
}
Expand All @@ -420,7 +420,7 @@ contract GatewayBase is Test {
dest: address(bytes20(keccak256("dummy_address"))),
destNetwork: DEST_NETWORK_ID,
gasLimit: 0,
salt: 1,
salt: 0,
data: new bytes(messageSize)
});

Expand Down Expand Up @@ -458,12 +458,13 @@ contract GatewayBase is Test {
emit IGateway.GmpCreated(
id, GmpSender.unwrap(gmp.source), gmp.dest, gmp.destNetwork, gmp.gasLimit, gmp.salt, gmp.data
);
ctx.gasLimit += 17100;
assertEq(ctx.submitMessage(gmp), id, "unexpected GMP id");

// Verify the execution cost
assertEq(
ctx.executionCost,
GasUtils.submitMessageGasCost(uint16(gmp.data.length)),
GasUtils.submitMessageGasCost(uint16(gmp.data.length)) + 17100,
"unexpected submit message gas cost"
);

Expand Down Expand Up @@ -622,7 +623,7 @@ contract GatewayBase is Test {
ctx.execute(sig, gmp);
}

function testSubmitGmpMessage() external {
function test_submitGmpMessage() external {
vm.txGasPrice(1);
GmpSender gmpSender = TestUtils.createTestAccount(1000 ether).toSender(false);
GmpMessage memory gmp = GmpMessage({
Expand All @@ -631,13 +632,13 @@ contract GatewayBase is Test {
dest: address(receiver),
destNetwork: DEST_NETWORK_ID,
gasLimit: 100_000,
salt: 1,
salt: 0,
data: abi.encodePacked(uint256(100_000))
});
bytes32 id = gmp.eip712hash();

// Check the previous message hash
assertEq(gateway.nonce(), 1, "wrong previous message hash");
assertEq(gateway.nonce(), 0, "wrong previous message hash");

CallOptions memory ctx = CallOptions({
from: gmpSender.toAddress(),
Expand Down Expand Up @@ -671,8 +672,8 @@ contract GatewayBase is Test {
assertEq(ctx.submitMessage(gmp), id, "unexpected GMP id");

// Verify the gas cost
uint256 expectedCost = GasUtils.submitMessageGasCost(uint16(gmp.data.length)) - 6500;
assertEq(ctx.executionCost, expectedCost, "unexpected execution gas cost in first call");
uint256 expectedCost = GasUtils.submitMessageGasCost(uint16(gmp.data.length)) - 4500;
assertEq(ctx.executionCost, expectedCost + 17100, "unexpected execution gas cost in first call");

// Now the second GMP message should have the salt equals to previous gmp hash
gmp.salt += 1;
Expand All @@ -684,7 +685,7 @@ contract GatewayBase is Test {
id, GmpSender.unwrap(gmp.source), gmp.dest, gmp.destNetwork, gmp.gasLimit, gmp.salt, gmp.data
);
assertEq(ctx.submitMessage(gmp), id, "unexpected GMP id");
assertEq(ctx.executionCost, expectedCost - 6800, "unexpected execution gas cost in second call");
assertEq(ctx.executionCost, expectedCost - 8800, "unexpected execution gas cost in second call");
}
}

Expand Down

0 comments on commit 7ff3387

Please sign in to comment.