-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
152 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Tests for the beneficiary account, especially for the lazy update of its balance to avoid | ||
// "implicit" dependency among consecutive transactions. | ||
// Currently, we randomly insert a beneficiary spending in the middle of the block. | ||
// TODO: Add more test scenarios around the beneficiary account's activities in the block. | ||
|
||
use rand::random; | ||
use revm::primitives::{alloy_primitives::U160, env::TxEnv, Address, BlockEnv, TransactTo, U256}; | ||
|
||
mod common; | ||
|
||
#[test] | ||
fn beneficiary() { | ||
let block_size = 100_000; // number of transactions | ||
let block_env = BlockEnv::default(); | ||
|
||
common::test_txs( | ||
block_env, | ||
// Mock `block_size` transactions sending some tokens to itself. | ||
// Skipping `Address::ZERO` as the beneficiary account. | ||
(1..=block_size) | ||
.map(|i| { | ||
// Randomly insert a beneficiary spending every ~256 txs | ||
let address = if random::<u8>() == 0 { | ||
Address::from(U160::from(0)) | ||
} else { | ||
Address::from(U160::from(i)) | ||
}; | ||
TxEnv { | ||
caller: address, | ||
transact_to: TransactTo::Call(address), | ||
value: U256::from(1), | ||
gas_price: U256::from(1), | ||
..TxEnv::default() | ||
} | ||
}) | ||
.collect(), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use std::{num::NonZeroUsize, thread}; | ||
|
||
use block_stm_revm::{BlockSTM, Storage}; | ||
use revm::{ | ||
primitives::{ | ||
alloy_primitives::U160, AccountInfo, Address, BlockEnv, ResultAndState, TxEnv, U256, | ||
}, | ||
DatabaseCommit, Evm, InMemoryDB, | ||
}; | ||
|
||
// Return an `InMemoryDB` for sequential usage and `Storage` for BlockSTM usage. | ||
// Both represent a "standard" mock state with prefilled accounts. | ||
// TODO: Mock pre-deployed contracts. | ||
fn mock_dbs(num_prefilled_accounts: usize) -> (InMemoryDB, Storage) { | ||
let mut sequential_db = InMemoryDB::default(); | ||
let mut block_stm_storage = Storage::default(); | ||
|
||
// Mock the beneficiary account (`Address:ZERO`) and the next `block_size` user accounts. | ||
// Filling half full accounts to have enough tokens for tests without worrying about the | ||
// corner case of balance not going beyond `U256::MAX`. | ||
let mock_account = AccountInfo::from_balance(U256::MAX.div_ceil(U256::from(2))); | ||
for i in 0..=num_prefilled_accounts { | ||
let address = Address::from(U160::from(i)); | ||
sequential_db.insert_account_info(address, mock_account.clone()); | ||
block_stm_storage.insert_account_info(address, mock_account.clone()); | ||
} | ||
|
||
(sequential_db, block_stm_storage) | ||
} | ||
|
||
// The source-of-truth sequential execution result that BlockSTM must match. | ||
fn execute_sequential( | ||
mut db: InMemoryDB, | ||
block_env: BlockEnv, | ||
txs: &[TxEnv], | ||
) -> Vec<ResultAndState> { | ||
txs.iter() | ||
.map(|tx| { | ||
let result_and_state = Evm::builder() | ||
.with_ref_db(&mut db) | ||
.with_block_env(block_env.clone()) | ||
.with_tx_env(tx.clone()) | ||
.build() | ||
.transact() | ||
// TODO: Proper error handling | ||
.unwrap(); | ||
db.commit(result_and_state.state.clone()); | ||
result_and_state | ||
}) | ||
.collect() | ||
} | ||
|
||
// Execute a list of transactions sequentially & with BlockSTM and assert that | ||
// the execution results match. | ||
pub(crate) fn test_txs(block_env: BlockEnv, txs: Vec<TxEnv>) { | ||
// TODO: Decouple the (number of) prefilled accounts with the number of transactions. | ||
let (sequential_db, block_stm_storage) = mock_dbs(txs.len()); | ||
let result_sequential = execute_sequential(sequential_db, block_env.clone(), &txs); | ||
let result_block_stm = BlockSTM::run( | ||
block_stm_storage, | ||
block_env, | ||
txs, | ||
thread::available_parallelism().unwrap_or(NonZeroUsize::MIN), | ||
); | ||
|
||
assert_eq!( | ||
result_sequential, result_block_stm, | ||
"Block-STM's execution result doesn't match Sequential's" | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Test raw transfers -- only send some ETH from one account to another without extra data. | ||
// Currently, we only have a no-state-conflict test of user account sending to themselves. | ||
// TODO: Add more tests of accounts cross-transferring to create state depdendencies. | ||
|
||
use revm::primitives::{alloy_primitives::U160, env::TxEnv, Address, BlockEnv, TransactTo, U256}; | ||
|
||
mod common; | ||
|
||
#[test] | ||
fn raw_transfers() { | ||
let block_size = 100_000; // number of transactions | ||
let block_env = BlockEnv::default(); | ||
|
||
common::test_txs( | ||
block_env, | ||
// Mock `block_size` transactions sending some tokens to itself. | ||
// Skipping `Address::ZERO` as the beneficiary account. | ||
(1..=block_size) | ||
.map(|i| { | ||
let address = Address::from(U160::from(i)); | ||
TxEnv { | ||
caller: address, | ||
transact_to: TransactTo::Call(address), | ||
value: U256::from(1), | ||
gas_price: U256::from(1), | ||
..TxEnv::default() | ||
} | ||
}) | ||
.collect(), | ||
); | ||
} |