100 lines
3.9 KiB
Rust
100 lines
3.9 KiB
Rust
use nu_block::types::{Block, RawTransaction, TxPayload, TxReceipt};
|
|
use nu_state::StateAccessor;
|
|
|
|
use crate::executor::{
|
|
execute_node_approve, execute_node_reject, execute_node_submit,
|
|
execute_stake_op, execute_token_transfer, execute_validator_register,
|
|
execute_vote_cast, execute_vote_register, execute_voting_open,
|
|
ExecutionContext,
|
|
};
|
|
|
|
pub struct BlockResult {
|
|
pub receipts: Vec<TxReceipt>,
|
|
pub applied: u32,
|
|
pub failed: u32,
|
|
}
|
|
|
|
pub fn execute_block(block: &Block, state: &dyn StateAccessor, now_ms: i64) -> BlockResult {
|
|
let dev_wallet = std::env::var("DEV_WALLET")
|
|
.unwrap_or_else(|_| "0xDEV0000000000000000000000000000000000000".to_string());
|
|
|
|
let mut receipts = Vec::with_capacity(block.transactions.len());
|
|
let mut applied = 0u32;
|
|
let mut failed = 0u32;
|
|
|
|
for tx in &block.transactions {
|
|
let receipt = execute_tx(tx, state, block.header.height, now_ms, &dev_wallet);
|
|
if receipt.success { applied += 1; } else { failed += 1; }
|
|
receipts.push(receipt);
|
|
}
|
|
|
|
BlockResult { receipts, applied, failed }
|
|
}
|
|
|
|
fn execute_tx(
|
|
tx: &RawTransaction,
|
|
state: &dyn StateAccessor,
|
|
block_height: u64,
|
|
now_ms: i64,
|
|
dev_wallet: &str,
|
|
) -> TxReceipt {
|
|
let ctx = ExecutionContext { state, block_height, now_ms };
|
|
|
|
let result = match &tx.payload {
|
|
TxPayload::TokenTransfer { to, amount } => {
|
|
execute_token_transfer(&ctx, &tx.sender, to, *amount, tx.fee, tx.nonce)
|
|
}
|
|
TxPayload::NodeSubmit { story_id, parent_node_id, content_hash, temp_id, entry_fee: _ } => {
|
|
execute_node_submit(&ctx, &tx.sender, tx.nonce, tx.fee, story_id, parent_node_id, content_hash, temp_id)
|
|
}
|
|
TxPayload::VoteRegister { node_id, stake_lock: _ } => {
|
|
execute_vote_register(&ctx, &tx.sender, tx.nonce, tx.fee, node_id)
|
|
}
|
|
TxPayload::VoteCast { node_id, approve } => {
|
|
execute_vote_cast(&ctx, &tx.sender, tx.nonce, tx.fee, node_id, *approve)
|
|
}
|
|
TxPayload::StakeOp { stake, amount } => {
|
|
execute_stake_op(&ctx, &tx.sender, tx.nonce, tx.fee, *stake, *amount)
|
|
}
|
|
TxPayload::ValidatorRegister { stake } => {
|
|
execute_validator_register(&ctx, &tx.sender, tx.nonce, tx.fee, *stake)
|
|
}
|
|
TxPayload::VotingOpen { node_id } => {
|
|
execute_voting_open(&ctx, node_id)
|
|
}
|
|
TxPayload::NodeApprove { temp_id, canonical_id } => {
|
|
execute_node_approve(&ctx, temp_id, canonical_id, dev_wallet)
|
|
}
|
|
TxPayload::NodeReject { node_id } => {
|
|
execute_node_reject(&ctx, node_id)
|
|
}
|
|
// Faz 2 later
|
|
TxPayload::NftMint { .. }
|
|
| TxPayload::NftTransfer { .. }
|
|
| TxPayload::CollectionClaim { .. } => {
|
|
Err(crate::errors::VmError::Unknown(format!("{} not yet implemented", payload_name(&tx.payload))))
|
|
}
|
|
};
|
|
|
|
match result {
|
|
Ok(()) => TxReceipt { tx_id: tx.tx_id.clone(), success: true, error: String::new() },
|
|
Err(e) => TxReceipt { tx_id: tx.tx_id.clone(), success: false, error: e.to_string() },
|
|
}
|
|
}
|
|
|
|
fn payload_name(payload: &TxPayload) -> &'static str {
|
|
match payload {
|
|
TxPayload::TokenTransfer { .. } => "TokenTransfer",
|
|
TxPayload::NodeSubmit { .. } => "NodeSubmit",
|
|
TxPayload::VoteRegister { .. } => "VoteRegister",
|
|
TxPayload::VoteCast { .. } => "VoteCast",
|
|
TxPayload::NftTransfer { .. } => "NftTransfer",
|
|
TxPayload::CollectionClaim { .. } => "CollectionClaim",
|
|
TxPayload::StakeOp { .. } => "StakeOp",
|
|
TxPayload::ValidatorRegister { .. } => "ValidatorRegister",
|
|
TxPayload::NodeApprove { .. } => "NodeApprove",
|
|
TxPayload::NftMint { .. } => "NftMint",
|
|
TxPayload::NodeReject { .. } => "NodeReject",
|
|
TxPayload::VotingOpen { .. } => "VotingOpen",
|
|
}
|
|
}
|