Skip to content

Commit

Permalink
chore: added commitment balance validation multiple test
Browse files Browse the repository at this point in the history
  • Loading branch information
merklefruit committed Jul 17, 2024
1 parent d99a29e commit 8fb651b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 5 deletions.
5 changes: 5 additions & 0 deletions bolt-sidecar/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ impl RpcClient {

self.0.request("debug_traceCall", params).await
}

/// Send a raw transaction to the network.
pub async fn send_raw_transaction(&self, raw: Bytes) -> TransportResult<B256> {
self.0.request("eth_sendRawTransaction", [raw]).await
}
}

impl Deref for RpcClient {
Expand Down
6 changes: 3 additions & 3 deletions bolt-sidecar/src/state/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ impl<C: StateFetcher> ExecutionState<C> {

(
nonce_diff_acc + nonce_diff,
balance_diff_acc + balance_diff,
balance_diff_acc.saturating_add(balance_diff),
u64::max(highest_slot, slot),
)
},
Expand Down Expand Up @@ -299,8 +299,8 @@ impl<C: StateFetcher> ExecutionState<C> {
};

let account_state_with_diffs = AccountState {
transaction_count: account_state.transaction_count + nonce_diff,
balance: account_state.balance - balance_diff,
transaction_count: account_state.transaction_count.saturating_add(nonce_diff),
balance: account_state.balance.saturating_sub(balance_diff),
has_code: account_state.has_code,
};

Expand Down
7 changes: 7 additions & 0 deletions bolt-sidecar/src/state/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@ impl StateFetcher for StateClient {
}
}

#[cfg(test)]
impl StateClient {
pub fn inner(&self) -> &RpcClient {
&self.client
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
67 changes: 65 additions & 2 deletions bolt-sidecar/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ impl Future for CommitmentDeadline {

#[cfg(test)]
mod tests {
use std::num::NonZero;
use std::{num::NonZero, str::FromStr};

use alloy_consensus::constants::ETH_TO_WEI;
use alloy_eips::eip2718::Encodable2718;
use alloy_network::EthereumWallet;
use alloy_primitives::{uint, Uint};
use alloy_primitives::{uint, Uint, U256};
use alloy_provider::{network::TransactionBuilder, Provider, ProviderBuilder};
use alloy_signer_local::PrivateKeySigner;
use execution::{ExecutionState, ValidationError};
Expand Down Expand Up @@ -189,6 +189,69 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn test_invalid_inclusion_request_balance_multiple() -> eyre::Result<()> {
let _ = tracing_subscriber::fmt::try_init();

let anvil = launch_anvil();
let client = StateClient::new(anvil.endpoint_url());

let max_comms = NonZero::new(10).unwrap();
let mut state = ExecutionState::new(client.clone(), max_comms).await?;

let sender = anvil.addresses().first().unwrap();
let sender_pk = anvil.keys().first().unwrap();
let signer = Signer::random();

// initialize the state by updating the head once
let slot = client.get_head().await?;
state.update_head(None, slot).await?;

// Set the sender balance to just enough to pay for 1 transaction
let balance = U256::from_str("500000000000000").unwrap(); // leave just 0.0005 ETH
let sender_account = client.get_account_state(sender, None).await.unwrap();
let balance_to_burn = sender_account.balance - balance;

// burn the balance
let tx = default_test_transaction(*sender, Some(0)).with_value(uint!(balance_to_burn));
let request = create_signed_commitment_request(tx, sender_pk, 10).await?;
let tx_bytes = request
.as_inclusion_request()
.unwrap()
.tx
.envelope_encoded();
let _ = client.inner().send_raw_transaction(tx_bytes).await?;

// wait for the transaction to be included to update the sender balance
tokio::time::sleep(Duration::from_secs(2)).await;
let slot = client.get_head().await?;
state.update_head(None, slot).await?;

// create a new transaction and request a preconfirmation for it
let tx = default_test_transaction(*sender, Some(1));
let request = create_signed_commitment_request(tx, sender_pk, 10).await?;

assert!(state.validate_commitment_request(&request).await.is_ok());

let message = ConstraintsMessage::build(0, request.as_inclusion_request().unwrap().clone());
let signature = signer.sign(&message.digest())?.to_string();
let signed_constraints = SignedConstraints { message, signature };
state.add_constraint(10, signed_constraints);

// create a new transaction and request a preconfirmation for it
let tx = default_test_transaction(*sender, Some(3));
let request = create_signed_commitment_request(tx, sender_pk, 10).await?;

// this should fail because the balance is insufficient as we spent
// all of it on the previous preconfirmation
assert!(matches!(
state.validate_commitment_request(&request).await,
Err(ValidationError::InsufficientBalance)
));

Ok(())
}

#[tokio::test]
async fn test_invalid_inclusion_request_basefee() -> eyre::Result<()> {
let _ = tracing_subscriber::fmt::try_init();
Expand Down

0 comments on commit 8fb651b

Please sign in to comment.