Have the Ethereum scheduler create Batches as necessary

Also introduces the fee logic, despite it being stubbed.
This commit is contained in:
Luke Parker
2024-09-20 00:12:54 -04:00
parent 8ea5acbacb
commit 4292660eda
4 changed files with 132 additions and 45 deletions

View File

@@ -5,13 +5,18 @@ use borsh::{BorshSerialize, BorshDeserialize};
use crate::primitives::{MAX_ADDRESS_LEN, ExternalAddress};
/// THe maximum amount of gas an address is allowed to specify as its gas limit.
///
/// Payments to an address with a gas limit which exceed this value will be dropped entirely.
pub const ADDRESS_GAS_LIMIT: u32 = 950_000;
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub struct ContractDeployment {
/// The gas limit to use for this contract's execution.
///
/// THis MUST be less than the Serai gas limit. The cost of it will be deducted from the amount
/// transferred.
gas: u32,
gas_limit: u32,
/// The initialization code of the contract to deploy.
///
/// This contract will be deployed (executing the initialization code). No further calls will
@@ -21,17 +26,23 @@ pub struct ContractDeployment {
/// A contract to deploy, enabling executing arbitrary code.
impl ContractDeployment {
pub fn new(gas: u32, code: Vec<u8>) -> Option<Self> {
pub fn new(gas_limit: u32, code: Vec<u8>) -> Option<Self> {
// Check the gas limit is less the address gas limit
if gas_limit > ADDRESS_GAS_LIMIT {
None?;
}
// The max address length, minus the type byte, minus the size of the gas
const MAX_CODE_LEN: usize = (MAX_ADDRESS_LEN as usize) - (1 + core::mem::size_of::<u32>());
if code.len() > MAX_CODE_LEN {
None?;
}
Some(Self { gas, code })
Some(Self { gas_limit, code })
}
pub fn gas(&self) -> u32 {
self.gas
pub fn gas_limit(&self) -> u32 {
self.gas_limit
}
pub fn code(&self) -> &[u8] {
&self.code
@@ -66,12 +77,18 @@ impl TryFrom<ExternalAddress> for Address {
Address::Address(address)
}
1 => {
let mut gas = [0xff; 4];
reader.read_exact(&mut gas).map_err(|_| ())?;
// The code is whatever's left since the ExternalAddress is a delimited container of
// appropriately bounded length
let mut gas_limit = [0xff; 4];
reader.read_exact(&mut gas_limit).map_err(|_| ())?;
Address::Contract(ContractDeployment {
gas: u32::from_le_bytes(gas),
gas_limit: {
let gas_limit = u32::from_le_bytes(gas_limit);
if gas_limit > ADDRESS_GAS_LIMIT {
Err(())?;
}
gas_limit
},
// The code is whatever's left since the ExternalAddress is a delimited container of
// appropriately bounded length
code: reader.to_vec(),
})
}
@@ -87,9 +104,9 @@ impl From<Address> for ExternalAddress {
res.push(0);
res.extend(&address);
}
Address::Contract(ContractDeployment { gas, code }) => {
Address::Contract(ContractDeployment { gas_limit, code }) => {
res.push(1);
res.extend(&gas.to_le_bytes());
res.extend(&gas_limit.to_le_bytes());
res.extend(&code);
}
}