Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce base fee #1390

Merged
merged 12 commits into from
May 15, 2024
1 change: 0 additions & 1 deletion builder/src/bin/permissioned-builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ async fn main() -> anyhow::Result<()> {
url: opt.l1_provider_url,
finalized_block: None,
events_max_block_range: 10000,
fee_contract_address: Default::default(),
};

let builder_key_pair = EthKeyPair::from_mnemonic(&opt.eth_mnemonic, opt.eth_account_index)?;
Expand Down
10 changes: 7 additions & 3 deletions builder/src/bin/permissionless-builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct NonPermissionedBuilderOptions {

/// Unique identifier for this instance of the sequencer network.
#[clap(long, env = "ESPRESSO_SEQUENCER_CHAIN_ID", default_value = "0")]
chain_id: u16,
chain_id: u64,

/// Maximum size in bytes of a block
#[clap(long, env = "ESPRESSO_SEQUENCER_MAX_BLOCK_SIZE", value_parser = parse_size)]
Expand Down Expand Up @@ -115,15 +115,19 @@ async fn main() -> anyhow::Result<()> {
url: opt.l1_provider_url,
finalized_block: None,
events_max_block_range: 10000,
fee_contract_address: Default::default(),
};

let builder_key_pair = EthKeyPair::from_mnemonic(&opt.eth_mnemonic, opt.eth_account_index)?;
let bootstrapped_view = ViewNumber::new(opt.view_number);

let builder_server_url: Url = format!("http://0.0.0.0:{}", opt.port).parse().unwrap();

let chain_config = ChainConfig::new(opt.chain_id, opt.max_block_size, opt.base_fee);
let chain_config = ChainConfig {
chain_id: opt.chain_id.into(),
max_block_size: opt.max_block_size,
base_fee: opt.base_fee.into(),
fee_contract: None,
};
let instance_state =
build_instance_state(l1_params, opt.state_peers, chain_config, sequencer_version).unwrap();

Expand Down
8 changes: 1 addition & 7 deletions builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,7 @@ pub mod testing {
let node_state = NodeState::new(
i as u64,
ChainConfig::default(),
L1Client::new(
self.anvil.endpoint().parse().unwrap(),
Address::default(),
1,
),
L1Client::new(self.anvil.endpoint().parse().unwrap(), 1),
MockStateCatchup::default(),
)
.with_genesis(ValidatedState::default());
Expand Down Expand Up @@ -535,7 +531,6 @@ pub mod testing {
ChainConfig::default(),
L1Client::new(
hotshot_test_config.get_anvil().endpoint().parse().unwrap(),
Address::default(),
1,
),
MockStateCatchup::default(),
Expand Down Expand Up @@ -600,7 +595,6 @@ pub mod testing {
ChainConfig::default(),
L1Client::new(
hotshot_test_config.get_anvil().endpoint().parse().unwrap(),
Address::default(),
1,
),
MockStateCatchup::default(),
Expand Down
18 changes: 12 additions & 6 deletions builder/src/non_permissioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,7 @@ pub fn build_instance_state<Ver: StaticVersionType + 'static>(
chain_config: ChainConfig,
_: Ver,
) -> anyhow::Result<NodeState> {
let l1_client = L1Client::new(
l1_params.url,
Address::default(),
l1_params.events_max_block_range,
);
let l1_client = L1Client::new(l1_params.url, l1_params.events_max_block_range);
let instance_state = NodeState::new(
u64::MAX, // dummy node ID, only used for debugging
chain_config,
Expand All @@ -91,6 +87,16 @@ impl BuilderConfig {
buffered_view_num_count: usize,
maximize_txns_count_timeout_duration: Duration,
) -> anyhow::Result<Self> {
tracing::info!(
address = %builder_key_pair.fee_account(),
?bootstrapped_view,
%channel_capacity,
?max_api_timeout_duration,
buffered_view_num_count,
?maximize_txns_count_timeout_duration,
"initializing builder",
);

// tx channel
let (tx_sender, tx_receiver) = broadcast::<MessageType<SeqTypes>>(channel_capacity.get());

Expand Down Expand Up @@ -153,7 +159,7 @@ impl BuilderConfig {
maximize_txns_count_timeout_duration,
instance_state
.chain_config()
.base_fee()
.base_fee
.as_u64()
.context("the base fee exceeds the maximum amount that a builder can pay (defined by u64::MAX)")?,
Arc::new(instance_state),
Expand Down
15 changes: 7 additions & 8 deletions builder/src/permissioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,15 +247,14 @@ pub async fn init_node<P: SequencerPersistence, Ver: StaticVersionType + 'static
genesis_state.prefund_account(address.into(), U256::max_value().into());
}

let l1_client = L1Client::new(
l1_params.url,
Address::default(),
l1_params.events_max_block_range,
);

let l1_client = L1Client::new(l1_params.url, l1_params.events_max_block_range);
let instance_state = NodeState::new(
node_index,
ChainConfig::new(0, max_block_size, base_fee),
ChainConfig {
max_block_size,
base_fee: base_fee.into(),
..Default::default()
},
l1_client,
Arc::new(StatePeers::<Ver>::from_urls(network_params.state_peers)),
);
Expand Down Expand Up @@ -447,7 +446,7 @@ impl<N: network::Type, P: SequencerPersistence, Ver: StaticVersionType + 'static
maximize_txns_count_timeout_duration,
instance_state
.chain_config()
.base_fee()
.base_fee
.as_u64()
.context("the base fee exceeds the maximum amount that a builder can pay (defined by u64::MAX)")?,
Arc::new(instance_state),
Expand Down
7 changes: 6 additions & 1 deletion data/header.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,10 @@
"block_merkle_tree_root": "MERKLE_COMM~yB4_Aqa35_PoskgTpcCR1oVLh6BUdLHIs7erHKWi-usUAAAAAAAAAAEAAAAAAAAAJg",
"fee_merkle_tree_root": "MERKLE_COMM~VJ9z239aP9GZDrHp3VxwPd_0l28Hc5KEAB1pFeCIxhYgAAAAAAAAAAIAAAAAAAAAdA",
"fee_info": { "account": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "amount": "0x0" },
"chain_config": { "chain_config": { "Left": { "chain_id": "0x8a19", "max_block_size": 10240, "base_fee": "0x0" } } }
"chain_config": { "chain_config": { "Left": {
"chain_id": "0x8a19",
"max_block_size": 10240,
"base_fee": "0x0",
"fee_contract": "0xa15bb66138824a1c7167f5e85b957d04dd34e468"
} } }
}
2 changes: 1 addition & 1 deletion sequencer/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod reference {
fn test_reference_header() {
reference_test::<Header, _>(
HEADER.clone(),
"BLOCK~00ISpu2jHbXD6z-BwMkwR4ijGdgUSoXLp_2jIStmqBrD",
"BLOCK~KOFxIeSaxl85Uwwo71iutIG3EMGShjfsrUXnKWZXWXcI",
|header| header.commit(),
);
}
Expand Down
7 changes: 5 additions & 2 deletions sequencer/src/block/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl<TableWord: TableWordTraits> Payload<TableWord> {
block_size += size_of::<TxTableEntry>() as u64;
}

if block_size > chain_config.max_block_size() {
if block_size > chain_config.max_block_size {
break;
}

Expand Down Expand Up @@ -372,7 +372,10 @@ mod test {
assert_eq!(tx_size, 10);

let n_txs = target_payload_total as u64 / tx_size;
let chain_config = ChainConfig::new(1, max_block_size, 1);
let chain_config = ChainConfig {
max_block_size,
..Default::default()
};

let mut txs = (0..n_txs)
.map(|_| Transaction::of_size(payload_size))
Expand Down
69 changes: 30 additions & 39 deletions sequencer/src/chain_config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::state::FeeAmount;
use committable::{Commitment, Committable};
use derive_more::{From, Into};
use ethers::types::U256;
use ethers::types::{Address, U256};
use itertools::Either;
use sequencer_utils::impl_to_fixed_bytes;
use serde::{Deserialize, Serialize};
Expand All @@ -11,8 +11,8 @@ pub struct ChainId(U256);

impl_to_fixed_bytes!(ChainId, U256);

impl From<u16> for ChainId {
fn from(id: u16) -> Self {
impl From<u64> for ChainId {
fn from(id: u64) -> Self {
Self(id.into())
}
}
Expand All @@ -21,47 +21,28 @@ impl From<u16> for ChainId {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ChainConfig {
/// Espresso chain ID
chain_id: ChainId,
pub chain_id: ChainId,
/// Maximum size in bytes of a block
max_block_size: u64,
pub max_block_size: u64,
/// Minimum fee in WEI per byte of payload
base_fee: FeeAmount,
pub base_fee: FeeAmount,
/// Fee contract address on L1.
///
/// This is optional so that fees can easily be toggled on/off, with no need to deploy a
/// contract when they are off. In a future release, after fees are switched on and thoroughly
/// tested, this may be made mandatory.
pub fee_contract: Option<Address>,
}

impl Default for ChainConfig {
fn default() -> Self {
Self::new(
U256::from(35353), // arbitrarily chosen chain ID
10240, // 10 kB max_block_size
0, // no fees
)
}
}

impl ChainConfig {
pub fn new(
chain_id: impl Into<ChainId>,
max_block_size: u64,
base_fee: impl Into<FeeAmount>,
) -> Self {
Self {
chain_id: chain_id.into(),
max_block_size,
base_fee: base_fee.into(),
chain_id: U256::from(35353).into(), // arbitrarily chosen chain ID
max_block_size: 10240,
base_fee: 0.into(),
fee_contract: None,
}
}

pub fn chain_id(&self) -> ChainId {
self.chain_id
}

pub fn max_block_size(&self) -> u64 {
self.max_block_size
}

pub fn base_fee(&self) -> FeeAmount {
self.base_fee
}
}

impl Committable for ChainConfig {
Expand All @@ -70,11 +51,16 @@ impl Committable for ChainConfig {
}

fn commit(&self) -> Commitment<Self> {
committable::RawCommitmentBuilder::new(&Self::tag())
let comm = committable::RawCommitmentBuilder::new(&Self::tag())
.fixed_size_field("chain_id", &self.chain_id.to_fixed_bytes())
.u64_field("max_block_size", self.max_block_size)
.fixed_size_field("base_fee", &self.base_fee.to_fixed_bytes())
.finalize()
.fixed_size_field("base_fee", &self.base_fee.to_fixed_bytes());
let comm = if let Some(addr) = self.fee_contract {
comm.u64_field("fee_contract", 1).fixed_size_bytes(&addr.0)
} else {
comm.u64_field("fee_contract", 0)
};
comm.finalize()
}
}

Expand Down Expand Up @@ -127,7 +113,12 @@ mod tests {
max_block_size,
..
} = chain_config;
let other_config = ChainConfig::new(chain_id, max_block_size, 1);
let other_config = ChainConfig {
chain_id,
max_block_size,
base_fee: 1.into(),
fee_contract: None,
};
assert!(chain_config != other_config);
}

Expand Down
22 changes: 13 additions & 9 deletions sequencer/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ impl BlockHeader<SeqTypes> for Header {
builder_fee: BuilderFee<SeqTypes>,
_vid_common: VidCommon,
) -> Result<Self, Self::Error> {
let chain_config = instance_state.chain_config;
let height = parent_leaf.get_height();
let view = parent_leaf.get_view_number();

Expand All @@ -305,10 +306,13 @@ impl BlockHeader<SeqTypes> for Header {
// Fetch the latest L1 snapshot.
let l1_snapshot = instance_state.l1_client().snapshot().await;
// Fetch the new L1 deposits between parent and current finalized L1 block.
let l1_deposits = if let Some(block_info) = l1_snapshot.finalized {
let l1_deposits = if let (Some(addr), Some(block_info)) =
(chain_config.fee_contract, l1_snapshot.finalized)
{
instance_state
.l1_client
.get_finalized_deposits(
addr,
parent_leaf
.get_block_header()
.l1_finalized
Expand Down Expand Up @@ -373,7 +377,7 @@ impl BlockHeader<SeqTypes> for Header {
builder_fee.fee_signature,
OffsetDateTime::now_utc().unix_timestamp() as u64,
validated_state,
instance_state.chain_config,
chain_config,
)?)
}

Expand Down Expand Up @@ -762,7 +766,10 @@ mod test_headers {

let result = validate_proposal(
&state,
ChainConfig::new(U256::zero(), 0u64, U256::zero()),
ChainConfig {
chain_id: U256::zero().into(),
..Default::default()
},
&parent_leaf,
&proposal,
&vid_common,
Expand Down Expand Up @@ -810,11 +817,8 @@ mod test_headers {
setup_backtrace();

let anvil = Anvil::new().block_time(1u32).spawn();
let mut genesis_state = NodeState::mock().with_l1(L1Client::new(
anvil.endpoint().parse().unwrap(),
Address::default(),
1,
));
let mut genesis_state =
NodeState::mock().with_l1(L1Client::new(anvil.endpoint().parse().unwrap(), 1));

let genesis = GenesisForTest::default();
let vid_common = vid_scheme(1).disperse([]).unwrap().common;
Expand Down Expand Up @@ -876,7 +880,7 @@ mod test_headers {
let mut proposal_state = parent_state.clone();
for fee_info in genesis_state
.l1_client
.get_finalized_deposits(None, 0)
.get_finalized_deposits(Address::default(), None, 0)
.await
{
proposal_state.insert_fee_deposit(fee_info).unwrap();
Expand Down
Loading