Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
392 changes: 359 additions & 33 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ console_error_panic_hook = "0.1.7"
prettytable-rs = "0.10.0"
clap = "4.5.50"
bincode = "2.0.1"
rue-compiler = "0.6.0"
rue-options = "0.6.0"
rue-lir = "0.6.0"

[profile.release]
lto = true
Expand Down
17 changes: 3 additions & 14 deletions crates/chia-sdk-bindings/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use chia_puzzle_types::{
offer::{NotarizedPayment as ChiaNotarizedPayment, Payment as ChiaPayment},
};
use chia_sdk_driver::{OptionMetadata, RewardDistributor as SdkRewardDistributor, SpendContext};
use chia_sdk_types::run_puzzle_with_cost;
use chialisp::classic::clvm_tools::stages::run;
use chialisp::classic::clvm_tools::stages::stage_0::TRunProgram;
use chialisp::classic::clvm_tools::{
Expand All @@ -15,7 +16,7 @@ use chialisp::classic::clvm_tools::{
use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm};
use clvm_utils::{TreeHash, tree_hash};
use clvmr::{
ChiaDialect, MEMPOOL_MODE, NodePtr, SExp, run_program,
NodePtr, SExp,
serde::{node_to_bytes, node_to_bytes_backrefs},
};
use num_bigint::BigInt;
Expand Down Expand Up @@ -59,21 +60,9 @@ impl Program {
}

pub fn run(&self, solution: Self, max_cost: u64, mempool_mode: bool) -> Result<Output> {
let mut flags = 0;

if mempool_mode {
flags |= MEMPOOL_MODE;
}

let mut ctx = self.0.lock().unwrap();

let reduction = run_program(
&mut ctx,
&ChiaDialect::new(flags),
self.1,
solution.1,
max_cost,
)?;
let reduction = run_puzzle_with_cost(&mut ctx, self.1, solution.1, max_cost, mempool_mode)?;

Ok(Output {
value: Program(self.0.clone(), reduction.1),
Expand Down
2 changes: 1 addition & 1 deletion crates/chia-sdk-driver/src/spend_bundle_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn spend_bundle_cost(coin_spends: &[CoinSpend]) -> Result<u64, DriverError>
for coin_spend in coin_spends {
let puzzle = coin_spend.puzzle_reveal.to_clvm(&mut allocator)?;
let solution = coin_spend.solution.to_clvm(&mut allocator)?;
let output = run_puzzle_with_cost(&mut allocator, puzzle, solution)?;
let output = run_puzzle_with_cost(&mut allocator, puzzle, solution, 11_000_000_000, false)?;
let conditions = Vec::<Condition>::from_clvm(&allocator, output.1)?;

cost += output.0;
Expand Down
1 change: 1 addition & 0 deletions crates/chia-sdk-signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ clvmr = { workspace = true }
thiserror = { workspace = true }
chia-sdk-types = { workspace = true }
k256 = { workspace = true }
rue-lir = { workspace = true }

[dev-dependencies]
chia-puzzle-types = { workspace = true }
Expand Down
32 changes: 29 additions & 3 deletions crates/chia-sdk-signer/src/required_signature.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use chia_protocol::CoinSpend;
use chia_sdk_types::Condition;
use chia_sdk_types::{Condition, is_debug_dialect_enabled};
use clvm_traits::{FromClvm, ToClvm};
use clvmr::{Allocator, ChiaDialect, run_program};
use clvmr::{
Allocator, ChiaDialect, ENABLE_KECCAK_OPS_OUTSIDE_GUARD, dialect::Dialect, run_program,
};
use rue_lir::DebugDialect;

use crate::{
AggSigConstants, RequiredBlsSignature, RequiredSecpSignature, SecpDialect, SignerError,
Expand All @@ -21,10 +24,33 @@ impl RequiredSignature {
allocator: &mut Allocator,
coin_spend: &CoinSpend,
constants: &AggSigConstants,
) -> Result<Vec<Self>, SignerError> {
if is_debug_dialect_enabled() {
Self::from_coin_spend_with_dialect(
allocator,
coin_spend,
constants,
DebugDialect::new(ENABLE_KECCAK_OPS_OUTSIDE_GUARD, false),
)
} else {
Self::from_coin_spend_with_dialect(
allocator,
coin_spend,
constants,
ChiaDialect::new(0),
)
}
}

fn from_coin_spend_with_dialect<D: Dialect>(
allocator: &mut Allocator,
coin_spend: &CoinSpend,
constants: &AggSigConstants,
dialect: D,
) -> Result<Vec<Self>, SignerError> {
let puzzle = coin_spend.puzzle_reveal.to_clvm(allocator)?;
let solution = coin_spend.solution.to_clvm(allocator)?;
let dialect = SecpDialect::new(ChiaDialect::new(0));
let dialect = SecpDialect::new(dialect);
let output = run_program(allocator, &dialect, puzzle, solution, 11_000_000_000)?.1;
let conditions = Vec::<Condition>::from_clvm(allocator, output)?;

Expand Down
1 change: 1 addition & 0 deletions crates/chia-sdk-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ futures-util = { workspace = true, optional = true }
prettytable-rs = {workspace = true }
serde = { workspace = true, features = ["derive"], optional = true }
bincode = { workspace = true, features = ["serde"], optional = true }
rue-lir = { workspace = true }

[package.metadata.cargo-machete]
ignored = ["prettytable-rs"]
11 changes: 3 additions & 8 deletions crates/chia-sdk-test/src/announcements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use chia_sdk_types::{
AssertCoinAnnouncement, AssertPuzzleAnnouncement, CreateCoinAnnouncement,
CreatePuzzleAnnouncement,
},
run_puzzle,
};
use clvm_traits::{FromClvm, ToClvm};
use clvmr::{Allocator, ChiaDialect, NodePtr, reduction::Reduction, run_program};
use clvmr::{Allocator, NodePtr};

#[derive(Debug, Default, Clone)]
pub struct Announcements {
Expand Down Expand Up @@ -120,13 +121,7 @@ pub fn announcements_for_spend(coin_spend: &CoinSpend) -> anyhow::Result<Announc
let puzzle = coin_spend.puzzle_reveal.to_clvm(allocator)?;
let solution = coin_spend.solution.to_clvm(allocator)?;

let Reduction(_cost, output) = run_program(
allocator,
&ChiaDialect::new(0),
puzzle,
solution,
11_000_000_000,
)?;
let output = run_puzzle(allocator, puzzle, solution)?;

let conditions = Vec::<NodePtr>::from_clvm(allocator, output)?;

Expand Down
11 changes: 8 additions & 3 deletions crates/chia-sdk-test/src/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use chia_bls::SecretKey;
use chia_consensus::validation_error::ErrorCode;
use chia_protocol::{Bytes32, Coin, CoinSpend, CoinState, Program, SpendBundle};
use chia_sdk_types::TESTNET11_CONSTANTS;
use clvmr::ENABLE_KECCAK_OPS_OUTSIDE_GUARD;
use indexmap::{IndexMap, IndexSet, indexset};
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
Expand Down Expand Up @@ -189,9 +190,13 @@ impl Simulator {
return Err(SimulatorError::Validation(ErrorCode::InvalidSpendBundle));
}

let conds =
validate_clvm_and_signature(&spend_bundle, 11_000_000_000 / 2, &TESTNET11_CONSTANTS, 0)
.map_err(SimulatorError::Validation)?;
let conds = validate_clvm_and_signature(
&spend_bundle,
11_000_000_000 / 2,
&TESTNET11_CONSTANTS,
ENABLE_KECCAK_OPS_OUTSIDE_GUARD,
)
.map_err(SimulatorError::Validation)?;

let puzzle_hashes: HashSet<Bytes32> =
conds.spends.iter().map(|spend| spend.puzzle_hash).collect();
Expand Down
88 changes: 82 additions & 6 deletions crates/chia-sdk-test/src/validate_clvm_and_signature.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
use chia_bls::{aggregate_verify_gt, hash_to_g2};
use chia_bls::{PublicKey, aggregate_verify_gt, hash_to_g2};
use chia_consensus::{
allocator::make_allocator, consensus_constants::ConsensusConstants,
owned_conditions::OwnedSpendBundleConditions, spendbundle_conditions::run_spendbundle,
validation_error::ErrorCode,
allocator::make_allocator,
conditions::{
ELIGIBLE_FOR_DEDUP, MempoolVisitor, ParseState, SpendBundleConditions,
process_single_spend, validate_conditions,
},
consensus_constants::ConsensusConstants,
flags::COMPUTE_FINGERPRINT,
owned_conditions::OwnedSpendBundleConditions,
puzzle_fingerprint::compute_puzzle_fingerprint,
run_block_generator::subtract_cost,
solution_generator::calculate_generator_length,
validation_error::{ErrorCode, ValidationErr},
};
use chia_protocol::SpendBundle;
use chia_protocol::{Bytes, SpendBundle};
use chia_sdk_types::run_puzzle_with_cost;
use chia_sha2::Sha256;
use clvmr::LIMIT_HEAP;
use clvm_utils::tree_hash;
use clvmr::{Allocator, LIMIT_HEAP, reduction::Reduction, serde::node_from_bytes};

// TODO: This function is copied here because WASM doesn't support std::time::Instant
// Should this be changed upstream?
Expand Down Expand Up @@ -49,3 +60,68 @@ pub fn validate_clvm_and_signature(
// Collect results
Ok(conditions)
}

// TODO: This function is copied here because the upstream doesn't support custom dialects, and
// we want to use the debug dialect for testing Rue puzzles in the simulator.
// Should this be changed upstream?
#[allow(clippy::type_complexity)]
pub fn run_spendbundle(
a: &mut Allocator,
spend_bundle: &SpendBundle,
max_cost: u64,
flags: u32,
constants: &ConsensusConstants,
) -> Result<(SpendBundleConditions, Vec<(PublicKey, Bytes)>), ValidationErr> {
// 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 mut ret = SpendBundleConditions::default();
let mut state = ParseState::default();
// We don't pay the size cost (nor execution cost) of being wrapped by a
// quote (in solution_generator).
let generator_length_without_quote = calculate_generator_length(&spend_bundle.coin_spends) - 2;

let byte_cost = generator_length_without_quote as u64 * constants.cost_per_byte;
subtract_cost(a, &mut cost_left, byte_cost)?;

for coin_spend in &spend_bundle.coin_spends {
// process the spend
let puz = node_from_bytes(a, coin_spend.puzzle_reveal.as_slice())?;
let sol = node_from_bytes(a, coin_spend.solution.as_slice())?;
let parent = a.new_atom(coin_spend.coin.parent_coin_info.as_slice())?;
let amount = a.new_number(coin_spend.coin.amount.into())?;
let Reduction(clvm_cost, conditions) = run_puzzle_with_cost(a, puz, sol, cost_left, false)?;

ret.execution_cost += clvm_cost;
subtract_cost(a, &mut cost_left, clvm_cost)?;

let buf = tree_hash(a, puz);
if coin_spend.coin.puzzle_hash != buf.into() {
return Err(ValidationErr(puz, ErrorCode::WrongPuzzleHash));
}
let puzzle_hash = a.new_atom(&buf)?;
let spend = process_single_spend::<MempoolVisitor>(
a,
&mut ret,
&mut state,
parent,
puzzle_hash,
amount,
conditions,
flags,
&mut cost_left,
clvm_cost,
constants,
)?;

if (spend.flags & ELIGIBLE_FOR_DEDUP) != 0 && (flags & COMPUTE_FINGERPRINT) != 0 {
spend.fingerprint = compute_puzzle_fingerprint(a, conditions)?;
}
}

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

assert!(max_cost >= cost_left);
ret.cost = max_cost - cost_left;
Ok((ret, state.pkm_pairs))
}
3 changes: 3 additions & 0 deletions crates/chia-sdk-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ clvmr = { workspace = true }
hex-literal = { workspace = true }
thiserror = { workspace = true }
chialisp = { workspace = true }
rue-compiler = { workspace = true }
rue-options = { workspace = true }
rue-lir = { workspace = true }

[dev-dependencies]
hex = { workspace = true }
Expand Down
4 changes: 4 additions & 0 deletions crates/chia-sdk-types/compile_rue_test.rue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main(a: Int, b: Int) -> Int {
debug a + b;
a * b + a + b
}
5 changes: 5 additions & 0 deletions crates/chia-sdk-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ pub use merkle_tree::*;
pub use payment_assertion::*;
pub use puzzle_mod::*;
pub use run_puzzle::*;

#[doc(hidden)]
pub mod __internals {
pub use clvm_utils::TreeHash;
}
Loading
Loading