Skip to content

Commit

Permalink
Merge pull request #267 from Chia-Network/fast-forward
Browse files Browse the repository at this point in the history
fast-forward
  • Loading branch information
arvidn committed Oct 23, 2023
2 parents 1941499 + 2f67799 commit fa8f3bf
Show file tree
Hide file tree
Showing 18 changed files with 1,165 additions and 6 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ clvmr = "=0.3.0"
hex = "=0.4.3"
pyo3 = { version = ">=0.19.0", optional = true }
clvm-utils = { version = "=0.2.7", path = "clvm-utils" }
chia-traits = { version = "=0.1.0", path = "chia-traits" }
clvm-traits = { version = "=0.1.0", path = "clvm-traits" }
clvm-derive = { version = "=0.1.0", path = "clvm-derive" }
chia-protocol = { version = "=0.2.7", path = "chia-protocol" }
chia-wallet = { version = "=0.1.0", path = "chia-wallet" }
hex-literal = "=0.4.1"
thiserror = "1.0.44"

Expand Down
6 changes: 6 additions & 0 deletions chia-protocol/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ impl<'a, const N: usize> From<&'a BytesImpl<N>> for &'a [u8; N] {
}
}

impl<const N: usize> From<&BytesImpl<N>> for [u8; N] {
fn from(v: &BytesImpl<N>) -> [u8; N] {
v.0
}
}

impl<'a, const N: usize> From<&'a BytesImpl<N>> for &'a [u8] {
fn from(v: &'a BytesImpl<N>) -> &'a [u8] {
&v.0
Expand Down
12 changes: 12 additions & 0 deletions chia-tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ chia-protocol = { version = "0.2.7", path = "../chia-protocol" }
chia-traits = { path = "../chia-traits" }
clvm-utils = { path = "../clvm-utils" }
clvm-traits = { path = "../clvm-traits" }
chia-wallet = { version = "=0.1.0", path = "../chia-wallet" }
clvmr = { version = "=0.3.0", features = ["counters"] }
chia = { version = "0.2.9", path = ".." }
sqlite = "=0.31.0"
clap = { version = "=4.3.9", features = ["derive"] }
zstd = "=0.12.3"
threadpool = "=1.8.1"
hex = "=0.4.3"
hex-literal = "=0.4.1"

[lib]
name = "chia_tools"
Expand All @@ -44,3 +46,13 @@ bench = false
name = "gen-corpus"
test = false
bench = false

[[bin]]
name = "run-spend"
test = false
bench = false

[[bin]]
name = "fast-forward-spend"
test = false
bench = false
77 changes: 77 additions & 0 deletions chia-tools/src/bin/fast-forward-spend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use clap::Parser;
use std::fs;
use std::io::Cursor;

use chia::fast_forward::fast_forward_singleton;
use chia_protocol::bytes::Bytes32;
use chia_protocol::{coin::Coin, coin_spend::CoinSpend, program::Program};
use chia_traits::streamable::Streamable;
use clvm_traits::{FromClvm, ToClvm};
use clvm_utils::tree_hash;
use clvmr::allocator::Allocator;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Path to CoinSpend file
#[arg(short, long)]
spend: String,

/// fast-forward the CoinSpend to spend a coin whose parent's parent is this
/// coin ID.
#[arg(short, long)]
new_parents_parent: String,

/// Save resulting CoinSpend to this file
#[arg(short, long)]
output_file: String,
}

fn main() {
let args = Args::parse();

let spend_bytes = fs::read(args.spend).expect("read file");
let spend = CoinSpend::parse(&mut Cursor::new(&spend_bytes)).expect("parse CoinSpend");

let new_parents_parent: Bytes32 = hex::decode(args.new_parents_parent)
.expect("invalid hex")
.as_slice()
.try_into()
.expect("parent_id");

let mut a = Allocator::new_limited(500000000, 62500000, 62500000);
let puzzle = spend.puzzle_reveal.to_clvm(&mut a).expect("to_clvm");
let solution = spend.solution.to_clvm(&mut a).expect("to_clvm");
let puzzle_hash = Bytes32::from(tree_hash(&a, puzzle));

let new_parent_coin = Coin {
parent_coin_info: new_parents_parent,
puzzle_hash,
amount: spend.coin.amount,
};

let new_coin = Coin {
parent_coin_info: new_parent_coin.coin_id().into(),
puzzle_hash,
amount: spend.coin.amount,
};

let new_solution = fast_forward_singleton(
&mut a,
puzzle,
solution,
&spend.coin,
&new_coin,
&new_parent_coin,
)
.expect("fast-forward");

let new_spend = CoinSpend {
coin: new_parent_coin,
puzzle_reveal: spend.puzzle_reveal,
solution: Program::from_clvm(&a, new_solution).expect("new solution"),
};
let mut bytes = Vec::<u8>::new();
new_spend.stream(&mut bytes).expect("stream CoinSpend");
fs::write(args.output_file, bytes).expect("write");
}
28 changes: 22 additions & 6 deletions chia-tools/src/bin/gen-corpus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use chia_traits::streamable::Streamable;

use chia_protocol::bytes::Bytes32;
use chia_protocol::{coin::Coin, coin_spend::CoinSpend, program::Program};
use chia_wallet::singleton::SINGLETON_TOP_LAYER_PUZZLE_HASH;
use clvm_traits::FromClvm;
use clvm_utils::{tree_hash, CurriedProgram};
use clvmr::allocator::NodePtr;
Expand Down Expand Up @@ -48,6 +49,7 @@ fn main() {
use std::collections::HashSet;
use std::sync::{Arc, Mutex};
let seen_puzzles = Arc::new(Mutex::new(HashSet::<Bytes32>::new()));
let seen_singletons = Arc::new(Mutex::new(HashSet::<Bytes32>::new()));

iterate_tx_blocks(
&args.file,
Expand All @@ -59,6 +61,7 @@ fn main() {
let prg = block.transactions_generator.unwrap();

let seen_puzzles = seen_puzzles.clone();
let seen_singletons = seen_singletons.clone();
pool.execute(move || {
let mut a = Allocator::new_limited(500000000, 62500000, 62500000);

Expand All @@ -76,10 +79,13 @@ fn main() {
_ => puzzle_hash,
};

if !seen_puzzles.lock().unwrap().insert(mod_hash) {
let run_puzzle = seen_puzzles.lock().unwrap().insert(mod_hash);
let fast_forward = (mod_hash == SINGLETON_TOP_LAYER_PUZZLE_HASH)
&& seen_singletons.lock().unwrap().insert(puzzle_hash);

if !run_puzzle && !fast_forward {
return;
}

use std::fs::write;

let puzzle_reveal = Program::from_clvm(a, puzzle).expect("puzzle reveal");
Expand All @@ -97,10 +103,20 @@ fn main() {

let mut bytes = Vec::<u8>::new();
spend.stream(&mut bytes).expect("stream CoinSpend");
let directory = "../fuzz/corpus/run-puzzle";
let _ = std::fs::create_dir_all(directory);
write(format!("{directory}/{mod_hash}.spend"), bytes).expect("write");
println!("{height}: {mod_hash}");
if run_puzzle {
let directory = "../fuzz/corpus/run-puzzle";
let _ = std::fs::create_dir_all(directory);
write(format!("{directory}/{mod_hash}.spend"), &bytes).expect("write");
println!("{height}: {mod_hash}");
}

if fast_forward {
let directory = "../fuzz/corpus/fast-forward";
let _ = std::fs::create_dir_all(directory);
write(format!("{directory}/{puzzle_hash}.spend"), bytes)
.expect("write");
println!("{height}: {puzzle_hash}");
}
},
)
.expect("failed to run block generator");
Expand Down
Loading

0 comments on commit fa8f3bf

Please sign in to comment.