Skip to content

Commit

Permalink
remove calls to run_block_generator in get_npc
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-o-how committed Jun 4, 2024
1 parent 19b375e commit 518ee44
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 41 deletions.
2 changes: 1 addition & 1 deletion crates/chia-consensus/src/gen/run_block_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use clvmr::run_program::run_program;
use clvmr::serde::{node_from_bytes, node_from_bytes_backrefs, node_from_bytes_backrefs_record};
use std::collections::{HashMap, HashSet};

fn subtract_cost(a: &Allocator, cost_left: &mut Cost, subtract: Cost) -> Result<(), ValidationErr> {
pub fn subtract_cost(a: &Allocator, cost_left: &mut Cost, subtract: Cost) -> Result<(), ValidationErr> {
if subtract > *cost_left {
Err(ValidationErr(a.nil(), ErrorCode::CostExceeded))
} else {
Expand Down
10 changes: 6 additions & 4 deletions crates/chia-consensus/src/multiprocess_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ use crate::gen::flags::{
use crate::gen::owned_conditions::OwnedSpendBundleConditions;
use crate::gen::solution_generator::solution_generator;
use crate::gen::validation_error::ErrorCode;
use crate::generator_types::BlockGenerator;
use crate::npc_result::get_name_puzzle_conditions;
use chia_bls::aggregate_verify;
use chia_bls::BlsCache;
use chia_bls::PublicKey;
use chia_protocol::Coin;
use chia_protocol::Program;
use chia_protocol::SpendBundle;
use chia_traits::Streamable;
use clvmr::{ENABLE_BLS_OPS_OUTSIDE_GUARD, ENABLE_FIXED_DIV};
use std::sync::{Arc, Mutex};
// use std::thread;
Expand Down Expand Up @@ -60,7 +57,11 @@ fn validate_clvm_and_signature(
let start_time = Instant::now();
let additional_data: chia_protocol::BytesImpl<32> = constants.agg_sig_me_additional_data;
let program: Vec<u8> = simple_solution_generator(spend_bundle)?;
let npcresult = get_name_puzzle_conditions(program, max_cost, true, height, &constants)?;
let npcresult = match get_name_puzzle_conditions(program, max_cost, true, height, &constants) {
Ok(result) => result,
Err(error) => return Err(error.1)
};

let (pks, msgs) = pkm_pairs(npcresult.clone(), additional_data.as_slice())?;
// Verify aggregated signature
if !{
Expand Down Expand Up @@ -171,6 +172,7 @@ mod tests {
use crate::consensus_constants::TEST_CONSTANTS;
use chia_bls::Signature;
use chia_protocol::CoinSpend;
use chia_protocol::Program;

#[test]
fn test_validate_no_pks() {
Expand Down
98 changes: 62 additions & 36 deletions crates/chia-consensus/src/npc_result.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
use crate::allocator::make_allocator;
use crate::consensus_constants::ConsensusConstants;
use crate::gen::conditions::EmptyVisitor;
use crate::gen::conditions::SpendBundleConditions;
use crate::gen::conditions::{process_single_spend, validate_conditions, EmptyVisitor, ParseState, SpendBundleConditions};
use clvm_utils::{tree_hash_cached, TreeHash};
use clvmr::run_program::run_program;
use clvmr::reduction::Reduction;
use crate::gen::flags::MEMPOOL_MODE;
use crate::gen::owned_conditions::OwnedSpendBundleConditions;
use crate::gen::run_block_generator::{run_block_generator, run_block_generator2};
use crate::gen::validation_error::{ErrorCode, ValidationErr};
use crate::gen::run_block_generator::{extract_n, subtract_cost};
use std::collections::{HashMap, HashSet};
use clvmr::chia_dialect::ChiaDialect;
use clvmr::serde::node_from_bytes;
use clvmr::allocator::{Allocator, NodePtr};
use crate::gen::validation_error::{first, ErrorCode, ValidationErr};
use crate::multiprocess_validation::get_flags_for_height_and_constants;
#[cfg(feature = "py-bindings")]
use chia_py_streamable_macro::{PyGetters, PyJsonDict, PyStreamable};
// #[cfg(feature = "py-bindings")]
// use chia_py_streamable_macro::{PyGetters, PyJsonDict, PyStreamable};
use clvmr::chia_dialect::LIMIT_HEAP;

// we may be able to remove this struct and just return a Rust native Result
Expand All @@ -32,39 +38,59 @@ pub fn get_name_puzzle_conditions(
mempool_mode: bool,
height: u32,
constants: &ConsensusConstants,
) -> Result<OwnedSpendBundleConditions, ErrorCode> {
) -> Result<OwnedSpendBundleConditions, ValidationErr> {
let mut flags = get_flags_for_height_and_constants(height, constants);
if mempool_mode {
flags |= MEMPOOL_MODE
};
let block_args = Vec::<Vec<u8>>::new();
let mut a2 = make_allocator(LIMIT_HEAP);
let sbc_result: Result<SpendBundleConditions, ValidationErr> =
if height >= constants.hard_fork_fix_height {
run_block_generator2::<_, EmptyVisitor>(
&mut a2,
generator_program.as_slice(),
&block_args,
max_cost,
flags,
)
} else {
run_block_generator::<_, EmptyVisitor>(
&mut a2,
generator_program.as_slice(),
&block_args,
max_cost,
flags,
)
};
match sbc_result {
Ok(sbc) => {
let result = OwnedSpendBundleConditions::from(&a2, sbc);
match result {
Ok(r) => Ok(r),
Err(_) => Err(ErrorCode::InvalidSpendBundle),
}
}
Err(e) => Err(e.1),
// below is an adapted version of the code from run_block_generators::run_block_generator2()
// it assumes no block references are passed in
let mut cost_left = max_cost;
let dialect = ChiaDialect::new(flags);
let mut a: Allocator = make_allocator(LIMIT_HEAP);
let program = node_from_bytes(&mut a, generator_program.as_slice())?;
let env = a.nil();
let Reduction(clvm_cost, mut all_spends) = run_program(&mut a, &dialect, program, env, cost_left)?;

subtract_cost(&a, &mut cost_left, clvm_cost)?;
all_spends = first(&a, all_spends)?;
let mut ret = SpendBundleConditions::default();
let mut state = ParseState::default();
let mut cache = HashMap::<NodePtr, TreeHash>::new();

while let Some((spend, rest)) = a.next(all_spends) {
all_spends = rest;
// process the spend
let [parent_id, puzzle, amount, solution, _spend_level_extra] =
extract_n::<5>(&a, spend, ErrorCode::InvalidCondition)?;

let Reduction(clvm_cost, conditions) =
run_program(&mut a, &dialect, puzzle, solution, cost_left)?;

subtract_cost(&a, &mut cost_left, clvm_cost)?;

let buf = tree_hash_cached(&a, puzzle, &HashSet::<NodePtr>::new(), &mut cache);
let puzzle_hash = a.new_atom(&buf)?;

process_single_spend::<EmptyVisitor>(
&a,
&mut ret,
&mut state,
parent_id,
puzzle_hash,
amount,
conditions,
flags,
&mut cost_left,
)?;
}
if a.atom_len(all_spends) != 0 {
return Err(ValidationErr(all_spends, ErrorCode::GeneratorRuntimeError));
}

validate_conditions(&a, &ret, state, a.nil(), flags)?;

ret.cost = max_cost - cost_left;
let Ok(osbc) = OwnedSpendBundleConditions::from(&a, ret) else {return Err(ValidationErr(all_spends, ErrorCode::InvalidSpendBundle))};
Ok(osbc)
}

0 comments on commit 518ee44

Please sign in to comment.