Skip to content

Commit ee80e9c

Browse files
committed
chore(solana): remove messenger layer [CHAIN-1567]
1 parent a922b44 commit ee80e9c

17 files changed

Lines changed: 132 additions & 404 deletions

File tree

base/src/Portal.sol

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ contract Portal is ReentrancyGuardTransient {
6868
// TODO: Re-estimate the constants.
6969
/// @notice Gas reserved for the execution logic between the `_hasMinGas` check and the actual Twin contract
7070
/// execution in `relayCall`.
71-
uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;
71+
uint64 public constant RELAY_CALL_CHECK_BUFFER_GAS = 5_000;
7272

7373
/// @notice Gas reserved for finalizing the execution of `relayCall` after the safe call.
74-
uint64 public constant POST_EXECUTION_RESERVED_GAS = 40_000;
74+
uint64 public constant RELAY_CALL_POST_EXECUTION_RESERVED_GAS = 40_000;
75+
76+
/// @notice Gas reserved for the dynamic parts of the `CALL` opcode.
77+
uint64 public constant RELAY_CALL_OVERHEAD_GAS = 40_000;
7578

7679
/// @notice Address of the trusted relayer.
7780
address public immutable TRUSTED_RELAYER;
@@ -153,7 +156,7 @@ contract Portal is ReentrancyGuardTransient {
153156
if (
154157
!_hasMinGas({
155158
minGas: minGasLimit,
156-
reservedGas: gasUsedForDeployment + POST_EXECUTION_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER
159+
reservedGas: gasUsedForDeployment + RELAY_CALL_POST_EXECUTION_RESERVED_GAS + RELAY_CALL_CHECK_BUFFER_GAS
157160
})
158161
) {
159162
failedCalls[callHash] = true;
@@ -168,7 +171,7 @@ contract Portal is ReentrancyGuardTransient {
168171
}
169172

170173
// Relay the calls via the Twin contract.
171-
try twin.executeBatch{gas: gasleft() - POST_EXECUTION_RESERVED_GAS, value: value}(call) {
174+
try twin.executeBatch{gas: gasleft() - RELAY_CALL_POST_EXECUTION_RESERVED_GAS, value: value}(call) {
172175
successfulCalls[callHash] = true;
173176
emit RelayedCall(callHash);
174177
} catch {
@@ -226,37 +229,38 @@ contract Portal is ReentrancyGuardTransient {
226229
/// https://github.com/ethereum-optimism/optimism/blob/4e9ef1aeffd2afd7a2378e2dc5efffa71f04207d/packages/contracts-bedrock/src/libraries/SafeCall.sol#L100
227230
///
228231
/// @dev !!!!! FOOTGUN ALERT !!!!!
229-
/// 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the
230-
/// `CALL` opcode's `address_access_cost`, `positive_value_cost`, and
231-
/// `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is
232-
/// still possible to self-rekt by initiating a withdrawal with a minimum gas limit
233-
/// that does not account for the `memory_expansion_cost` & `code_execution_cost`
234-
/// factors of the dynamic cost of the `CALL` opcode.
235-
/// 2.) This function should *directly* precede the external call if possible. There is an
236-
/// added buffer to account for gas consumed between this check and the call, but it
237-
/// is only 5,700 gas.
238-
/// 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call
239-
/// frame may be passed to a subcontext, we need to ensure that the gas will not be
240-
/// truncated.
232+
/// 1.) The RELAY_CALL_OVERHEAD_GAS base buffer is to account for the worst case of the dynamic cost of the
233+
/// `CALL` opcode's `address_access_cost`, `positive_value_cost`, and `value_to_empty_account_cost` factors
234+
/// with an added buffer of 5,700 gas. It is still possible to self-rekt by initiating a withdrawal with a
235+
/// minimum gas limit that does not account for the `memory_expansion_cost` & `code_execution_cost` factors
236+
/// of the dynamic cost of the `CALL` opcode.
237+
/// 2.) This function should *directly* precede the external call if possible. There is an added buffer to
238+
/// account for gas consumed between this check and the call, but it is only 5,700 gas.
239+
/// 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call frame may be passed
240+
/// to a subcontext, we need to ensure that the gas will not be truncated.
241241
/// 4.) Use wisely. This function is not a silver bullet.
242242
///
243243
/// @param minGas Minimum amount of gas that is forwarded to the Solana sender's Twin contract.
244244
/// @param reservedGas Amount of gas that is reserved for the caller after the execution of the target context.
245245
///
246246
/// @return hasMinGas `true` if there is enough gas remaining to safely supply `minGas` to the target
247-
/// context as well as reserve `reservedGas` for the caller after the execution of
248-
/// the target context.
247+
/// context as well as reserve `reservedGas` for the caller after the execution of
248+
/// the target context.
249249
function _hasMinGas(uint256 minGas, uint256 reservedGas) private view returns (bool hasMinGas) {
250250
assembly {
251251
// Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)
252-
hasMinGas := iszero(lt(mul(gas(), 63), add(mul(minGas, 64), mul(add(40000, reservedGas), 63))))
252+
hasMinGas :=
253+
iszero(lt(mul(gas(), 63), add(mul(minGas, 64), mul(add(RELAY_CALL_OVERHEAD_GAS, reservedGas), 63))))
253254
}
254255
}
255256

256257
/// @notice Checks whether the ISM verification is successful.
257258
///
258259
/// @dev TODO: Plug some ISM verification here.
259260
function _ismVerify(bytes calldata call, bytes calldata ismData) private pure {
261+
call; // Silence unused variable warning.
262+
ismData; // Silence unused variable warning.
263+
260264
// TODO: Plug some ISM verification here.
261265
require(true, ISMVerificationFailed());
262266
}

solana/programs/portal/src/constants.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use anchor_lang::prelude::*;
2-
use hex_literal::hex;
32

43
// Portal constants
54

@@ -13,10 +12,6 @@ pub const GAS_FEE_RECEIVER: Pubkey = pubkey!("CB8GXDdZDSD5uqfeow1qfp48ouayxXGpw7
1312
#[cfg(not(any(test, feature = "test-env")))]
1413
pub const GAS_FEE_RECEIVER: Pubkey = pubkey!("eEwCrQLBdQchykrkYitkYUZskd7MPrU2YxBXcPDPnMt");
1514

16-
pub const GAS_PER_BYTE_COST: u64 = 40;
17-
18-
pub const BASE_TRANSACTION_COST: u64 = 21000;
19-
2015
pub const GAS_COST_SCALER_DP: u64 = 10u64.pow(6);
2116
pub const GAS_COST_SCALER: u64 = 1_000_000;
2217

@@ -45,9 +40,3 @@ pub const EIP1559_DEFAULT_WINDOW_DURATION_SECONDS: u64 = 1; // 1 second windows
4540
pub const EIP1559_DEFAULT_GAS_TARGET_PER_WINDOW: u64 = 5_000_000; // 5M gas per window
4641

4742
pub const EIP1559_DEFAULT_ADJUSTMENT_DENOMINATOR: u64 = 2;
48-
49-
// Messenger constants
50-
51-
pub const MESSENGER_SEED: &[u8] = b"messenger";
52-
53-
pub const REMOTE_MESSENGER_ADDRESS: [u8; 20] = hex!("2c85Bb93B4c1F07E80a242FfB3Fa9c0e8b72BB00");

solana/programs/portal/src/instructions/initialize.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,12 @@
11
use anchor_lang::prelude::*;
22

3-
use crate::{
4-
constants::{EIP1559_SEED, MESSENGER_SEED},
5-
state::{Eip1559, Messenger},
6-
};
3+
use crate::{constants::EIP1559_SEED, state::Eip1559};
74

85
#[derive(Accounts)]
96
pub struct Initialize<'info> {
107
#[account(mut)]
118
pub payer: Signer<'info>,
129

13-
#[account(
14-
init,
15-
payer = payer,
16-
seeds = [MESSENGER_SEED],
17-
bump,
18-
space = 8 + Messenger::INIT_SPACE
19-
)]
20-
pub messenger: Account<'info, Messenger>,
21-
2210
#[account(
2311
init,
2412
payer = payer,
@@ -74,13 +62,11 @@ mod tests {
7462
mock_clock(&mut svm, 1747440000); // May 16th, 2025
7563

7664
// Find the PDAs
77-
let (messenger, _) = Pubkey::find_program_address(&[MESSENGER_SEED], &PORTAL_PROGRAM_ID);
7865
let (eip1559, _) = Pubkey::find_program_address(&[EIP1559_SEED], &PORTAL_PROGRAM_ID);
7966

8067
// Build the instruction
8168
let initialize_accounts = crate::accounts::Initialize {
8269
payer: payer_pk,
83-
messenger,
8470
eip1559,
8571
system_program: solana_sdk_ids::system_program::ID,
8672
}
@@ -102,13 +88,6 @@ mod tests {
10288
let result = svm.send_transaction(tx);
10389
assert!(result.is_ok(), "Transaction should succeed: {:?}", result);
10490

105-
// Assert the expected messenger account data
106-
let messenger_account = svm.get_account(&messenger).unwrap();
107-
assert_eq!(messenger_account.owner, PORTAL_PROGRAM_ID);
108-
109-
let messenger_data = Messenger::try_deserialize(&mut &messenger_account.data[..]).unwrap();
110-
assert_eq!(messenger_data.nonce, 0);
111-
11291
// Assert the expected Eip1559 account data
11392
let eip1559_account = svm.get_account(&eip1559).unwrap();
11493
assert_eq!(eip1559_account.owner, PORTAL_PROGRAM_ID);
Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
pub mod send_call;
2-
pub mod send_message;
32

43
pub use send_call::*;
5-
pub use send_message::*;
64

7-
use anchor_lang::prelude::Pubkey;
5+
use anchor_lang::prelude::*;
86

7+
#[derive(Debug, Copy, Clone, AnchorSerialize, AnchorDeserialize)]
8+
#[repr(u8)]
9+
pub enum CallType {
10+
Call,
11+
DelegateCall,
12+
Create,
13+
Create2,
14+
}
15+
16+
#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)]
917
pub struct Call {
18+
pub ty: CallType,
1019
pub from: Pubkey,
1120
pub to: [u8; 20],
12-
pub gas_limit: u64,
13-
pub is_creation: bool,
21+
pub min_gas_limit: u64,
1422
pub data: Vec<u8>,
1523
}

0 commit comments

Comments
 (0)