Skip to content

Commit

Permalink
add squash writeset when executing genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
simonjiao committed Dec 28, 2024
1 parent d3d4a21 commit 6be4fd0
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 40 deletions.
23 changes: 15 additions & 8 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,10 +697,10 @@ impl BlockChain {
txn_accumulator,
block_accumulator,
&genesis_epoch,
None,
None, /*parent status*/
genesis_block,
&chain_id,
None,
None, /*VM metrics*/
)?;
dag = Self::init_dag(dag, genesis_header)?;
Self::new(time_service, executed_block.block.id(), storage, None, dag)
Expand Down Expand Up @@ -1269,12 +1269,19 @@ impl BlockChain {
};

watch(CHAIN_WATCH_NAME, "n21");
let executed_data = starcoin_executor::block_execute(
&statedb,
transactions.clone(),
epoch.block_gas_limit(),
vm_metrics,
)?;
let executed_data = if header.is_genesis() {
starcoin_executor::execute_genesis_transaction(
&statedb,
transactions.first().unwrap().clone(),
)?
} else {
starcoin_executor::block_execute(
&statedb,
transactions.clone(),
epoch.block_gas_limit(),
vm_metrics,
)?
};
watch(CHAIN_WATCH_NAME, "n22");
let state_root = executed_data.state_root;
let vec_transaction_info = &executed_data.txn_infos;
Expand Down
73 changes: 66 additions & 7 deletions executor/src/block_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ use crate::execute_block_transactions;
use serde::{Deserialize, Serialize};
use starcoin_crypto::HashValue;
use starcoin_state_api::{ChainStateReader, ChainStateWriter};
use starcoin_types::error::BlockExecutorError;
use starcoin_types::error::ExecutorResult;
use starcoin_types::transaction::TransactionStatus;
use starcoin_types::transaction::{Transaction, TransactionInfo};
use starcoin_types::{
error::{BlockExecutorError, ExecutorResult},
transaction::{Transaction, TransactionInfo, TransactionStatus},
vm_error::KeptVMStatus,
};
use starcoin_vm_runtime::metrics::VMMetrics;
use starcoin_vm_types::contract_event::ContractEvent;
use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use starcoin_vm_types::write_set::WriteSet;
use starcoin_vm_types::{
contract_event::ContractEvent,
state_store::table::{TableHandle, TableInfo},
write_set::WriteSet,
StateView,
};
use std::collections::BTreeMap;

#[cfg(feature = "force-deploy")]
Expand Down Expand Up @@ -64,6 +68,57 @@ impl Default for BlockExecutedData {
}
}

pub fn execute_genesis_transaction<S: StateView + ChainStateWriter + Sync>(
chain_state: &S,
genesis_txn: Transaction,
) -> ExecutorResult<BlockExecutedData> {
let txn_hash = genesis_txn.id();
let txn_outputs = execute_block_transactions(chain_state, vec![genesis_txn], u64::MAX, None)
.map_err(BlockExecutorError::BlockTransactionExecuteErr)?;
assert_eq!(
txn_outputs.len(),
1,
"genesis txn output count must be 1, but got {}",
txn_outputs.len()
);
let mut executed_data = BlockExecutedData::default();
let (write_set, events, gas_used, status, _) =
txn_outputs.first().unwrap().clone().into_inner();
let extra_write_set =
extract_extra_writeset(chain_state).expect("extract extra writeset failed");
let write_set = write_set
.into_mut()
.squash(extra_write_set.into_mut())
.expect("failed to squash write set")
.freeze()
.expect("failed to freeze write set");
match status {
TransactionStatus::Keep(status) => {
assert_eq!(status, KeptVMStatus::Executed);
chain_state
.apply_write_set(write_set.clone())
.map_err(BlockExecutorError::BlockChainStateErr)?;

let txn_state_root = chain_state
.commit()
.map_err(BlockExecutorError::BlockChainStateErr)?;
executed_data.state_root = txn_state_root;
executed_data.txn_infos.push(TransactionInfo::new(
txn_hash,
txn_state_root,
events.as_slice(),
gas_used,
status,
));
executed_data.txn_events.push(events);
executed_data.write_sets.push(write_set);
}
_ => unreachable!("genesis txn output must be keep"),
}

Ok(executed_data)
}

pub fn block_execute<S: ChainStateReader + ChainStateWriter + Sync>(
chain_state: &S,
txns: Vec<Transaction>,
Expand Down Expand Up @@ -170,6 +225,10 @@ fn create_force_upgrade_extra_txn<S: ChainStateReader + ChainStateWriter>(
)
}

fn extract_extra_writeset<S: StateView>(_chain_state: &S) -> anyhow::Result<WriteSet> {
Ok(WriteSet::default())
}

// todo: check the execute_extra_txn in OpenedBlock, and merge with it
#[cfg(feature = "force-deploy")]
fn execute_extra_txn<S: ChainStateReader + ChainStateWriter>(
Expand Down
2 changes: 1 addition & 1 deletion executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#[macro_use]
extern crate log;

pub use block_executor::{block_execute, BlockExecutedData};
pub use block_executor::{block_execute, execute_genesis_transaction, BlockExecutedData};
pub use executor::*;
// pub use starcoin_transaction_builder::{
// build_accept_token_txn, build_batch_transfer_txn, build_transfer_from_association,
Expand Down
29 changes: 5 additions & 24 deletions genesis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

mod errors;

use anyhow::{bail, ensure, format_err, Result};
use anyhow::{bail, format_err, Result};
pub use errors::GenesisError;
use include_dir::include_dir;
use include_dir::Dir;
Expand Down Expand Up @@ -32,7 +32,6 @@ use starcoin_vm_types::{
account_config::CORE_CODE_ADDRESS,
state_store::StateView,
transaction::{RawUserTransaction, SignedUserTransaction, TransactionPayload},
vm_status::KeptVMStatus,
};
use std::{
fmt::Display,
Expand Down Expand Up @@ -186,31 +185,13 @@ impl Genesis {
txn: SignedUserTransaction,
) -> Result<TransactionInfo> {
let txn = Transaction::UserTransaction(txn);
let txn_hash = txn.id();

let output = starcoin_executor::execute_transactions(chain_state, vec![txn], None)?
let output = starcoin_executor::execute_genesis_transaction(chain_state, txn)?
.txn_infos
.pop()
.expect("Execute output must exist.");
let (write_set, events, gas_used, status, _) = output.into_inner();
assert_eq!(gas_used, 0, "Genesis txn output's gas_used must be zero");
let keep_status = status
.status()
.map_err(|e| format_err!("Genesis txn is discard by: {:?}", e))?;
ensure!(
keep_status == KeptVMStatus::Executed,
"Genesis txn execute fail for: {:?}",
keep_status
);
chain_state.apply_write_set(write_set)?;
let state_root = chain_state.commit()?;
chain_state.flush()?;
Ok(TransactionInfo::new(
txn_hash,
state_root,
events.as_slice(),
gas_used,
keep_status,
))

Ok(output)
}

pub fn block(&self) -> &Block {
Expand Down

0 comments on commit 6be4fd0

Please sign in to comment.