Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
71 changes: 49 additions & 22 deletions crates/full-node/sov-rollup-apis/src/endpoints/constants.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
use axum::extract::State;
use axum::response::IntoResponse as _;
use axum::routing::get;
use axum::Router;
use serde::Serialize;
use sov_modules_api::macros::config_value;
use sov_rest_utils::preconfigured_router_layers;

/// Trait for the `/rollup/constant` endpoint.
pub trait ConstantsEndpoint: Clone + Send + Sync + 'static {
/// The response data returned by the `schema` endpoint.
type Response: Serialize;

/// Handles the `schema` request.
/// Should return the [`Constants`] as a JSON object string.
fn handler(&self) -> Self::Response;

/// Returns a configured axum router for the schema endpoint.
///
/// Calls the implemented [`ConstantsEndpoint::handler`] and returns the result.
/// If [`ConstantsEndpoint::handler`] returns a error then it will be included in the
/// [`sov_rest_utils::ErrorObject`]s details field.
///
/// # Warning
///
/// If you override this method you should ensure you provide the standard schema path. If the
/// path is different then external tooling like web3 SDKs won't be able to consume the
/// functionality and will fail to work.
fn axum_router(&self) -> Router<()> {
preconfigured_router_layers(
Router::new().route(
"/rollup/constants",
get(|State(state): State<Self>| async move {
axum::Json(state.handler()).into_response()
})
.with_state(self.clone()),
),
)
}
}

/// The response returned by the `/rollup/constants` endpoint.
///
/// For simplicity we currently only return a subset of constants that are useful
/// for clientside applications.
#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub struct ConstantsResponse {
chain_id: u64,
chain_name: &'static str,
hyperlane_domain: u32,
address_prefix: &'static str,
/// the chain-id
pub chain_id: u64,
/// the chain-name
pub chain_name: String,
/// hyperlane domain for warp routes
pub hyperlane_domain: u32,
/// the address prefix
pub address_prefix: &'static str,
}

impl Default for ConstantsResponse {
fn default() -> Self {
Self {
chain_id: config_value!("CHAIN_ID"),
chain_name: config_value!("CHAIN_NAME"),
hyperlane_domain: config_value!("HYPERLANE_BRIDGE_DOMAIN"),
address_prefix: config_value!("ADDRESS_PREFIX"),
}
}
}
impl ConstantsEndpoint for ConstantsResponse {
type Response = Self;

/// Returns an axum router configured to serve `/rollup/constants` requests
pub fn axum_router() -> Router<()> {
preconfigured_router_layers(Router::new().route(
"/rollup/constants",
get(|| async move { axum::Json(ConstantsResponse::default()) }),
))
fn handler(&self) -> Self::Response {
self.clone()
}
}
3 changes: 1 addition & 2 deletions crates/full-node/sov-rollup-apis/src/endpoints/simulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use sov_modules_api::capabilities::{
AuthorizationData, ChainState, TransactionAuthorizer, UniquenessData,
};
use sov_modules_api::common::Amount;
use sov_modules_api::macros::config_value;
use sov_modules_api::prelude::anyhow;
use sov_modules_api::sov_universal_wallet::schema::{RollupRoots, SchemaError};
use sov_modules_api::transaction::{Credentials, PriorityFeeBips, TxDetails};
Expand Down Expand Up @@ -271,7 +270,7 @@ impl<S: Spec, R: Runtime<S>> SovereignSimulate<S, R> {
.transpose()
.map_err(|e| SimulateError::InvalidInput(format!("{e:?}")))?;
Ok(TxDetails {
chain_id: config_value!("CHAIN_ID"),
chain_id: *sov_modules_api::CHAIN_ID,
max_priority_fee_bips: partial
.max_priority_fee_bips
.unwrap_or(PriorityFeeBips::ZERO),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ use sov_modules_api::capabilities::{
BatchFromUnregisteredSequencer, FatalError, TransactionAuthenticator, UniquenessData,
UnregisteredAuthenticationError,
};
use sov_modules_api::macros::config_value;
use sov_modules_api::runtime::capabilities::AuthenticationError;
use sov_modules_api::transaction::{
AuthenticatedTransactionAndRawHash, AuthenticatedTransactionData, Credentials, PriorityFeeBips,
TxDetails,
};
use sov_modules_api::StateReader;
use sov_modules_api::VersionReader;
use sov_modules_api::CHAIN_ID;
use sov_modules_api::{
DispatchCall, FullyBakedTx, Gas, GetGasPrice, ProvableStateReader, RawTx, Runtime, Spec,
};
Expand Down Expand Up @@ -184,7 +184,7 @@ fn validate_chain_id(
tx_chain_id: Option<u64>,
tx_hash: TxHash,
) -> Result<u64, AuthenticationError> {
let rollup_chain_id = config_value!("CHAIN_ID");
let rollup_chain_id = *CHAIN_ID;
let tx_chain_id = tx_chain_id.ok_or(AuthenticationError::FatalError(
FatalError::MissingChainId(rollup_chain_id),
tx_hash,
Expand Down Expand Up @@ -284,7 +284,7 @@ where
))?;
let tx_chain_id = match request.chain_id {
Some(chain_id) => validate_chain_id(Some(chain_id), sentinel_tx_hash)?,
None => config_value!("CHAIN_ID"),
None => *CHAIN_ID,
};
let authenticated_tx = build_authenticated_tx_data::<_, S>(
sentinel_tx_hash,
Expand Down Expand Up @@ -450,7 +450,8 @@ where
let (tx_and_raw_hash, auth_data, runtime_call) =
sov_modules_api::capabilities::authenticate::<_, S, Rt>(
&tx.data,
&Rt::CHAIN_HASH,
*CHAIN_ID,
&Rt::chain_hash(),
state,
)?;

Expand Down
2 changes: 1 addition & 1 deletion crates/module-system/sov-cli/src/workflows/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ where
Ok(UnsignedTransactionWithoutUniqueness::new(
tx,
chain_id,
RT::CHAIN_HASH,
RT::chain_hash(),
max_priority_fee_bips.into(),
max_fee,
gas_limit,
Expand Down
7 changes: 4 additions & 3 deletions crates/module-system/sov-eip712-auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sov_modules_api::transaction::{
};
use sov_modules_api::{
DispatchCall, FullyBakedTx, GasMeter, MeteredBorshDeserialize, MeteredBorshDeserializeError,
ProvableStateReader, RawTx, Runtime, Spec, TxHash, VersionReader,
ProvableStateReader, RawTx, Runtime, Spec, TxHash, VersionReader, CHAIN_ID,
};
use sov_state::User;

Expand Down Expand Up @@ -130,7 +130,8 @@ where
Eip712AuthenticatorInput::Standard(tx) => {
sov_modules_api::capabilities::authenticate::<_, S, Rt>(
&tx.data,
&Rt::CHAIN_HASH,
*CHAIN_ID,
&Rt::chain_hash(),
state,
)
}
Expand Down Expand Up @@ -255,7 +256,7 @@ fn verify_and_decode_tx<
}
};

verify_chain_id(details, raw_tx_hash)?;
verify_chain_id(details, raw_tx_hash, *CHAIN_ID)?;
verify_eip712_signature::<S, D, SP>(&tx, raw_tx_hash, meter)?;

let tx_and_raw_hash = AuthenticatedTransactionAndRawHash {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ use crate::transaction::{
#[cfg(feature = "native")]
use crate::CryptoSpecExt;
use crate::GetGasPrice;
use crate::CHAIN_ID;
use crate::{
capabilities, CryptoSpec, DispatchCall, FullyBakedTx, GasMeter, GasMeteringError,
MeteredBorshDeserialize, MeteredBorshDeserializeError, MeteredHasher, ProvableStateReader,
RawTx, Runtime, Spec, VersionReader,
};

/// The chain ID of the rollup.
/// The default chain ID of the rollup.
pub fn config_chain_id() -> u64 {
config_value_private!("CHAIN_ID")
*CHAIN_ID
}

/// Resolves all valid chain hashes for a given height using configured overrides.
Expand Down Expand Up @@ -212,7 +213,12 @@ where
capabilities::fatal_deserialization_error::<_, S, _>(&tx.data, e, pre_exec_ws)
})?;

crate::capabilities::authenticate::<_, S, Rt>(&input.data, &Rt::CHAIN_HASH, pre_exec_ws)
crate::capabilities::authenticate::<_, S, Rt>(
&input.data,
*CHAIN_ID,
&Rt::chain_hash(),
pre_exec_ws,
)
}

#[cfg(feature = "native")]
Expand Down Expand Up @@ -351,11 +357,12 @@ impl From<AuthenticationError> for UnregisteredAuthenticationError {
pub fn verify_chain_id<S: Spec>(
tx_details: &TxDetails<S>,
raw_tx_hash: TxHash,
expected_chain_id: u64,
) -> Result<(), AuthenticationError> {
if tx_details.chain_id != config_chain_id() {
if tx_details.chain_id != expected_chain_id {
return Err(AuthenticationError::FatalError(
FatalError::InvalidChainId {
expected: config_chain_id(),
expected: expected_chain_id,
got: tx_details.chain_id,
},
raw_tx_hash,
Expand Down Expand Up @@ -420,14 +427,15 @@ fn verify_signature<S: Spec, D: DispatchCall<Spec = S>>(
pub fn verify_and_decode_tx<S: Spec, D: DispatchCall<Spec = S>>(
raw_tx_hash: TxHash,
tx: Transaction<D, S>,
expected_chain_id: u64,
chain_hash: &[u8; 32],
meter: &mut impl GasMeter<Spec = S>,
) -> Result<AuthenticationOutput<S, D::Decodable>, AuthenticationError> {
let resolved_hashes = crate::runtime::ResolvedChainHashes {
primary: *chain_hash,
grace_period_hashes: Vec::new(),
};
verify_and_decode_tx_multi_hash(raw_tx_hash, tx, resolved_hashes, meter)
verify_and_decode_tx_multi_hash(raw_tx_hash, tx, expected_chain_id, resolved_hashes, meter)
}

/// Authenticate raw sov-transaction.
Expand All @@ -445,6 +453,7 @@ pub fn authenticate<
D: DispatchCall<Spec = S>,
>(
mut raw_tx: &[u8],
expected_chain_id: u64,
default_chain_hash: &[u8; 32],
state: &mut Accessor,
) -> Result<AuthenticationOutput<S, D::Decodable>, AuthenticationError> {
Expand Down Expand Up @@ -483,7 +492,13 @@ pub fn authenticate<
));
}

verify_and_decode_tx_multi_hash::<S, D>(raw_tx_hash, tx, resolved_hashes, state)
verify_and_decode_tx_multi_hash::<S, D>(
raw_tx_hash,
tx,
expected_chain_id,
resolved_hashes,
state,
)
}

/// Authenticate and verify deserialized sov-tx with multiple chain hashes.
Expand All @@ -493,6 +508,7 @@ pub fn authenticate<
fn verify_and_decode_tx_multi_hash<S: Spec, D: DispatchCall<Spec = S>>(
raw_tx_hash: TxHash,
tx: Transaction<D, S>,
expected_chain_id: u64,
resolved_hashes: crate::runtime::ResolvedChainHashes,
meter: &mut impl GasMeter<Spec = S>,
) -> Result<AuthenticationOutput<S, D::Decodable>, AuthenticationError> {
Expand All @@ -508,7 +524,7 @@ fn verify_and_decode_tx_multi_hash<S: Spec, D: DispatchCall<Spec = S>>(
}
};

verify_chain_id(details, raw_tx_hash)?;
verify_chain_id(details, raw_tx_hash, expected_chain_id)?;

// Try signature verification with each valid chain hash
let mut last_error = None;
Expand Down Expand Up @@ -548,12 +564,16 @@ pub fn authenticate_unregistered<
pre_exec_ws: &mut Accessor,
) -> Result<AuthenticationOutput<S, Rt::Decodable>, UnregisteredAuthenticationError> {
let (tx_and_raw_hash, auth_data, runtime_call) =
authenticate::<_, S, Rt>(raw_tx, &Rt::CHAIN_HASH, pre_exec_ws).map_err(|e| match e {
AuthenticationError::FatalError(err, hash) => {
UnregisteredAuthenticationError::FatalError(err, hash)
}
AuthenticationError::OutOfGas(err) => UnregisteredAuthenticationError::OutOfGas(err),
})?;
authenticate::<_, S, Rt>(raw_tx, *CHAIN_ID, &Rt::chain_hash(), pre_exec_ws).map_err(
|e| match e {
AuthenticationError::FatalError(err, hash) => {
UnregisteredAuthenticationError::FatalError(err, hash)
}
AuthenticationError::OutOfGas(err) => {
UnregisteredAuthenticationError::OutOfGas(err)
}
},
)?;
Ok((tx_and_raw_hash, auth_data, runtime_call))
}

Expand Down
Loading
Loading