Skip to content

Commit

Permalink
rusk: fix high gas limit TXs taking longer
Browse files Browse the repository at this point in the history
- Add `fork` method to `RuskState` allowing for copying the underlying
  `NetworkState`
- Change `execute_state_transition` to keep transactions based on
  `gas_spent` instead of `gas_limit`

Resolves: #605
  • Loading branch information
ureeves committed Mar 1, 2022
1 parent 8fcc220 commit f1d36e9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
41 changes: 27 additions & 14 deletions rusk/src/lib/services/state.rs
Expand Up @@ -173,6 +173,7 @@ impl State for Rusk {
info!("Received ExecuteStateTransition request");

let mut state = self.state()?;
let mut forked_state = state.fork();

let request = request.into_inner();

Expand All @@ -183,25 +184,37 @@ impl State for Rusk {

// Here we discard transactions that:
// - Fail parsing
// - Have a gas limit that is larger than the running `block_gas_left`.
// - Spend more gas than the running `block_gas_left`
for tx in request.txs {
if let Ok(tx) = Transaction::from_slice(&tx.payload) {
let gas_limit = tx.fee().gas_limit;

if gas_limit <= block_gas_left {
let mut gas_meter = GasMeter::with_limit(gas_limit);
let mut gas_meter = GasMeter::with_limit(tx.fee().gas_limit);

// We do not care if the transaction fails or succeeds here
let _ = forked_state.execute::<()>(
request.block_height,
tx.clone(),
&mut gas_meter,
);

let gas_spent = gas_meter.spent();

// If the transaction executes with more gas than is left in the
// block reject it and re-fork the state
if gas_spent > block_gas_left {
forked_state = state.fork();
continue;
}

// We do not care if the transaction fails or succeeds here
let _ = state.execute::<()>(
request.block_height,
tx.clone(),
&mut gas_meter,
);
block_gas_left -= gas_spent;
dusk_spent += gas_spent * tx.fee().gas_price;

dusk_spent += gas_meter.spent() * tx.fee().gas_price;
block_gas_left -= gas_meter.spent();
state = forked_state.fork();
txs.push((tx, gas_meter).into());

txs.push((tx, gas_meter).into());
// No need to keep executing if there is no gas left in the
// block
if block_gas_left == 0 {
break;
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions rusk/src/lib/state.rs
Expand Up @@ -58,6 +58,12 @@ impl RuskState {
self.0.lock().reset()
}

/// Fork the underlying network state, returning a new `RuskState`.
pub fn fork(&self) -> Self {
let network = self.0.lock().clone();
Self(Arc::new(Mutex::new(network)))
}

/// Executes a transaction on the state via the Transfer Contract
pub fn execute<R>(
&mut self,
Expand Down

0 comments on commit f1d36e9

Please sign in to comment.