Skip to content

Commit 26e45a3

Browse files
committed
A mess but we're properly connected to the simulator
1 parent 253338e commit 26e45a3

File tree

6 files changed

+107
-41
lines changed

6 files changed

+107
-41
lines changed

src/channel_handler/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::channel_handler::types::{
1919
use crate::common::constants::{CREATE_COIN, REM};
2020
use crate::common::standard_coin::{
2121
ChiaIdentity, agg_sig_me_message, aggregate_public_keys, partial_signer, private_to_public_key,
22-
puzzle_for_pk, puzzle_hash_for_pk, sign_agg_sig_me, standard_solution,
22+
puzzle_for_pk, puzzle_hash_for_pk, sign_agg_sig_me, standard_solution_unsafe,
2323
standard_solution_partial, unsafe_sign_partial,
2424
};
2525
use crate::common::types::{
@@ -303,6 +303,7 @@ impl ChannelHandler {
303303
create_conditions_with_rem,
304304
&aggregated_key_for_unroll_create,
305305
&env.agg_sig_me_additional_data,
306+
true
306307
)
307308
}
308309

@@ -944,6 +945,7 @@ impl ChannelHandler {
944945
conditions,
945946
&aggregate_public_key,
946947
&env.agg_sig_me_additional_data,
948+
true
947949
)?;
948950
Ok(TransactionBundle {
949951
solution,
@@ -973,6 +975,7 @@ impl ChannelHandler {
973975
conditions,
974976
&aggregate_public_key,
975977
&env.agg_sig_me_additional_data,
978+
false
976979
)?;
977980

978981
Ok((state_channel_coin.clone(), solution, signature))
@@ -1475,7 +1478,7 @@ impl ChannelHandler {
14751478

14761479
coins_with_solutions.push(TransactionBundle {
14771480
puzzle: spend_coin_puzzle.clone(),
1478-
solution: standard_solution(
1481+
solution: standard_solution_unsafe(
14791482
env.allocator,
14801483
&self.referee_private_key(),
14811484
conditions,

src/common/standard_coin.rs

+28-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use chia_bls;
77
use clvm_traits::{clvm_curried_args, ToClvm};
88

99
use clvmr::allocator::NodePtr;
10-
use clvm_tools_rs::util::number_from_u8;
10+
use clvm_tools_rs::util::{number_from_u8, u8_from_number};
1111

1212
use clvm_tools_rs::classic::clvm::__type_compatibility__::{
1313
Bytes, Stream, UnvalidatedBytesFromType,
@@ -87,6 +87,23 @@ fn test_calculate_synthetic_offset() {
8787
assert_eq!(offset, want_offset);
8888
}
8989

90+
pub fn calculate_synthetic_secret_key(secret_key: &PrivateKey, hidden_puzzle_hash: &Hash) -> Result<PrivateKey, types::Error> {
91+
let secret_exponent_bytes = secret_key.bytes();
92+
let secret_exponent = number_from_u8(&secret_exponent_bytes);
93+
let public_key = private_to_public_key(secret_key);
94+
let synthetic_secret_offset = calculate_synthetic_offset(&public_key, &PuzzleHash::from_hash(hidden_puzzle_hash.clone()));
95+
let synthetic_secret_exponent = (secret_exponent + synthetic_secret_offset) % group_order_int();
96+
let private_key_bytes_right = u8_from_number(synthetic_secret_exponent);
97+
let mut private_key_bytes: [u8; 32] = [0; 32];
98+
for (i, b) in private_key_bytes_right.iter().enumerate() {
99+
private_key_bytes[i + 32 - private_key_bytes.len()] = *b;
100+
}
101+
PrivateKey::from_bytes(&private_key_bytes)
102+
.map(Ok)
103+
.unwrap_or_else(|e| Err(format!("calculate_synthetic_public_key: {e:?}")))
104+
.into_gen()
105+
}
106+
90107
pub fn calculate_synthetic_public_key(
91108
public_key: &PublicKey,
92109
hidden_puzzle_hash: &PuzzleHash,
@@ -369,7 +386,7 @@ pub fn sign_agg_sig_me(
369386
signed
370387
}
371388

372-
pub fn standard_solution(
389+
pub fn standard_solution_unsafe(
373390
allocator: &mut AllocEncoder,
374391
private_key: &PrivateKey,
375392
conditions: NodePtr,
@@ -384,10 +401,11 @@ pub fn standard_solution(
384401
pub fn standard_solution_partial(
385402
allocator: &mut AllocEncoder,
386403
private_key: &PrivateKey,
387-
unroll_coin_parent: &CoinID,
404+
parent_coin: &CoinID,
388405
conditions: NodePtr,
389406
aggregate_public_key: &PublicKey,
390407
agg_sig_me_additional_data: &Hash,
408+
partial: bool,
391409
) -> Result<(NodePtr, Aggsig), types::Error> {
392410
// Fairly certain i understand that because of the property that
393411
// (SK1 + SK2).sign((PK1 + PK2) || msg) ==
@@ -423,20 +441,24 @@ pub fn standard_solution_partial(
423441
CoinCondition::CreateCoin(_ph) => {
424442
let agg_sig_me_message = agg_sig_me_message(
425443
&quoted_conds_hash.bytes(),
426-
unroll_coin_parent,
444+
parent_coin,
427445
agg_sig_me_additional_data,
428446
);
429447
eprintln!("public_key {aggregate_public_key:?} {agg_sig_me_message:?}");
430448
add_signature(
431449
&mut aggregated_signature,
432-
partial_signer(private_key, aggregate_public_key, &agg_sig_me_message),
450+
if partial {
451+
partial_signer(private_key, &aggregate_public_key, &agg_sig_me_message)
452+
} else {
453+
private_key.sign(&agg_sig_me_message)
454+
}
433455
);
434456
}
435457
CoinCondition::AggSigMe(pubkey, data) => {
436458
let mut message = pubkey.bytes().to_vec();
437459
message.extend_from_slice(&data);
438460
let agg_sig_me_message =
439-
agg_sig_me_message(&message, unroll_coin_parent, agg_sig_me_additional_data);
461+
agg_sig_me_message(&message, parent_coin, agg_sig_me_additional_data);
440462
add_signature(
441463
&mut aggregated_signature,
442464
partial_signer(private_key, &pubkey, &agg_sig_me_message),

src/common/types.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use clvm_traits::{ClvmEncoder, ToClvm, ToClvmError};
2828
use clvm_tools_rs::compiler::runtypes::RunFailure;
2929

3030
/// CoinID
31-
#[derive(Default, Clone)]
31+
#[derive(Default, Clone, Debug)]
3232
pub struct CoinID(Hash);
3333

3434
impl CoinID {
@@ -58,6 +58,9 @@ impl CoinString {
5858
let mut allocator = AllocEncoder::new();
5959
let amount_clvm = amount.to_clvm(&mut allocator).unwrap();
6060
let mut res = Vec::new();
61+
eprintln!("parent {parent:?}");
62+
eprintln!("puzzle_hash {puzzle_hash:?}");
63+
eprintln!("amount {amount:?}");
6164
res.append(&mut parent.bytes().to_vec());
6265
res.append(&mut puzzle_hash.bytes().to_vec());
6366
res.append(&mut allocator.allocator().atom(amount_clvm).to_vec());
@@ -380,7 +383,7 @@ impl Hash {
380383
}
381384
pub fn from_slice(by: &[u8]) -> Hash {
382385
let mut fixed: [u8; 32] = [0; 32];
383-
for (i, b) in by.iter().enumerate() {
386+
for (i, b) in by.iter().enumerate().take(32) {
384387
fixed[i % 32] = *b;
385388
}
386389
Hash::from_bytes(fixed)

src/referee.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::channel_handler::types::{GameStartInfo, ReadableMove, ReadableUX};
1515
use crate::common::constants::CREATE_COIN;
1616
use crate::common::standard_coin::{
1717
curry_and_treehash, private_to_public_key, puzzle_for_pk, puzzle_hash_for_pk, sign_agg_sig_me,
18-
standard_solution, ChiaIdentity,
18+
standard_solution_unsafe, ChiaIdentity,
1919
};
2020
use crate::common::types::{
2121
u64_from_atom, usize_from_atom, Aggsig, AllocEncoder, Amount, CoinCondition, CoinString, Error,
@@ -672,7 +672,7 @@ impl RefereeMaker {
672672
// XXX puzzle_reveal
673673
(CREATE_COIN, (puzzle_hash.clone(), (self.amount.clone(), ()))).to_clvm(allocator).into_gen()?;
674674
let (solution, sig) =
675-
standard_solution(allocator, &self.my_identity.private_key, inner_conditions)?;
675+
standard_solution_unsafe(allocator, &self.my_identity.private_key, inner_conditions)?;
676676
let args_list: Vec<Node> = [
677677
previous_state.game_move.move_made.to_clvm(allocator).into_gen()?,
678678
previous_state
@@ -733,7 +733,11 @@ impl RefereeMaker {
733733
.to_clvm(allocator)
734734
.into_gen()?;
735735
let (solution, sig) =
736-
standard_solution(allocator, &self.my_identity.private_key, inner_conditions)?;
736+
standard_solution_unsafe(
737+
allocator,
738+
&self.my_identity.private_key,
739+
inner_conditions
740+
)?;
737741
let args_list: Vec<Node> = [
738742
current_state.game_move.move_made.to_clvm(allocator).into_gen()?,
739743
current_state
@@ -1117,7 +1121,11 @@ impl RefereeMaker {
11171121
.into_gen()?;
11181122

11191123
let (slash_solution, slash_aggsig) =
1120-
standard_solution(allocator, &self.my_identity.private_key, slash_conditions)?;
1124+
standard_solution_unsafe(
1125+
allocator,
1126+
&self.my_identity.private_key,
1127+
slash_conditions
1128+
)?;
11211129

11221130
let (state, validation_program) = {
11231131
let current_state = self.current_state();

src/tests/simulator.rs

+51-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use clvmr::allocator::NodePtr;
22
use clvm_traits::ToClvm;
33

4+
use clvm_tools_rs::classic::clvm_tools::binutils::disassemble;
5+
46
use pyo3::prelude::*;
57
use pyo3::types::{PyNone, PyBytes, PyTuple};
68
use rand::prelude::*;
@@ -9,10 +11,9 @@ use rand_chacha::ChaCha8Rng;
911

1012
use indoc::indoc;
1113

12-
use crate::common::constants::CREATE_COIN;
13-
use crate::common::standard_coin::standard_solution;
14-
use crate::common::types::{ErrToError, Error, Puzzle, Amount, Hash, CoinString, CoinID, PuzzleHash, PrivateKey, Aggsig, Node, SpecificTransactionBundle, AllocEncoder, TransactionBundle};
15-
use crate::common::standard_coin::ChiaIdentity;
14+
use crate::common::constants::{AGG_SIG_ME_ADDITIONAL_DATA, CREATE_COIN, DEFAULT_HIDDEN_PUZZLE_HASH};
15+
use crate::common::standard_coin::{sign_agg_sig_me, standard_solution_partial, ChiaIdentity, calculate_synthetic_secret_key, private_to_public_key, calculate_synthetic_public_key, agg_sig_me_message};
16+
use crate::common::types::{ErrToError, Error, Puzzle, Amount, Hash, CoinString, CoinID, PuzzleHash, PrivateKey, Aggsig, Node, SpecificTransactionBundle, AllocEncoder, TransactionBundle, ToQuotedProgram, Sha256tree};
1617

1718
// Allow simulator from rust.
1819
struct Simulator {
@@ -127,6 +128,8 @@ impl Simulator {
127128
let mut result_coins = Vec::new();
128129
for i in items.iter() {
129130
let coin_of_item: PyObject = i.getattr(py, "coin")?.extract(py)?;
131+
let as_list_str: String = coin_of_item.call_method0(py, "__repr__")?.extract(py)?;
132+
eprintln!("as_list_str {as_list_str}");
130133
let as_list: Vec<PyObject> = self.coin_as_list.call1(py, (coin_of_item,))?.extract(py)?;
131134
let parent_coin_info: &PyBytes = as_list[0].downcast(py)?;
132135
let parent_coin_info_slice: &[u8] = parent_coin_info.extract()?;
@@ -231,6 +234,8 @@ impl Simulator {
231234
let (inclusion_status, err): (PyObject, PyObject) = spend_res.extract(py)?;
232235
eprintln!("inclusion_status {inclusion_status}");
233236
let status: u32 = inclusion_status.extract(py)?;
237+
let e: String = err.call_method0(py, "__repr__")?.extract(py)?;
238+
eprintln!("err {e:?}");
234239
Ok(status)
235240
})
236241
}
@@ -241,13 +246,16 @@ fn test_sim() {
241246
let seed: [u8; 32] = [0; 32];
242247
let mut rng = ChaCha8Rng::from_seed(seed);
243248
let mut allocator = AllocEncoder::new();
249+
let agg_sig_me_additional_data = Hash::from_slice(&AGG_SIG_ME_ADDITIONAL_DATA);
244250
let s = Simulator::new();
245251
let private_key: PrivateKey = rng.gen();
246252
let identity = ChiaIdentity::new(&mut allocator, private_key.clone()).expect("should create");
253+
eprintln!("identity public key {:?}", identity.public_key);
247254
s.farm_block(&identity.puzzle_hash);
248255

249256
let coins = s.get_my_coins(&identity.puzzle_hash).expect("got coins");
250-
eprintln!("coins {coins:?}");
257+
eprintln!("coin 0 {:?}", coins[0].to_parts());
258+
eprintln!("coin 0 id {:?}", coins[0].to_coin_id());
251259

252260
let (first_coin_parent, first_coin_ph, first_coin_amt) = coins[0].to_parts().unwrap();
253261
assert_eq!(first_coin_ph, identity.puzzle_hash);
@@ -258,38 +266,56 @@ fn test_sim() {
258266
(Amount::new(1), ())
259267
)
260268
),
261-
(CREATE_COIN,
262-
(identity.puzzle_hash.clone(),
263-
(first_coin_amt - Amount::new(1), ())
264-
)
265-
)
269+
// (CREATE_COIN,
270+
// (identity.puzzle_hash.clone(),
271+
// (first_coin_amt - Amount::new(1), ())
272+
// )
273+
// )
266274
].to_clvm(&mut allocator).expect("should create conditions");
267275

268-
let (solution, signature) = standard_solution(
276+
let default_hidden_puzzle_hash = Hash::from_bytes(DEFAULT_HIDDEN_PUZZLE_HASH.clone());
277+
let synthetic_secret_key = calculate_synthetic_secret_key(
278+
&identity.private_key,
279+
&default_hidden_puzzle_hash
280+
).expect("should be ok");
281+
let synthetic_public_key = private_to_public_key(&synthetic_secret_key);
282+
assert_eq!(
283+
synthetic_public_key,
284+
calculate_synthetic_public_key(
285+
&identity.public_key,
286+
&PuzzleHash::from_hash(default_hidden_puzzle_hash.clone())
287+
).expect("should be ok")
288+
);
289+
let (solution, signature1) = standard_solution_partial(
269290
&mut allocator,
270-
&private_key,
271-
conditions
291+
&synthetic_secret_key,
292+
&coins[0].to_coin_id(),
293+
conditions,
294+
&synthetic_public_key,
295+
&agg_sig_me_additional_data,
296+
false
272297
).expect("should build");
273298

274-
let spend =
275-
Python::with_gil(|py| {
276-
s.make_coin_spend(
277-
py,
278-
&mut allocator,
279-
&CoinString::from_parts(&CoinID::default(), &PuzzleHash::default(), &Amount::default()),
280-
identity.puzzle.clone(),
281-
solution
282-
)
283-
}).expect("should get a spend");
299+
let quoted_conds = conditions.to_quoted_program(&mut allocator).expect("should work");
300+
let hashed_conds = quoted_conds.sha256tree(&mut allocator);
301+
let agg_sig_me_message = agg_sig_me_message(
302+
&hashed_conds.bytes(),
303+
&coins[0].to_coin_id(),
304+
&agg_sig_me_additional_data
305+
);
306+
eprintln!("our message {agg_sig_me_message:?}");
307+
let signature2 = synthetic_secret_key.sign(&agg_sig_me_message);
308+
assert_eq!(signature1, signature2);
284309

285-
eprintln!("spend {spend:?}");
310+
eprintln!("our cond hash {hashed_conds:?}");
311+
eprintln!("our signature {signature1:?}");
286312

287313
let specific = SpecificTransactionBundle {
288314
coin: coins[0].clone(),
289315
bundle: TransactionBundle {
290316
puzzle: identity.puzzle.clone(),
291317
solution,
292-
signature,
318+
signature: signature1,
293319
}
294320
};
295321

src/tests/standard_coin.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::common::constants::{DEFAULT_HIDDEN_PUZZLE_HASH, ONE, TWO};
1111
use crate::common::standard_coin::{
1212
calculate_hash_of_quoted_mod_hash, calculate_synthetic_public_key, curry_and_treehash,
1313
get_standard_coin_puzzle, hex_to_sexp, partial_signer, private_to_public_key, puzzle_for_pk,
14-
puzzle_hash_for_pk, standard_solution, unsafe_sign_partial,
14+
puzzle_hash_for_pk, standard_solution_unsafe, unsafe_sign_partial,
1515
};
1616
use crate::common::types::{
1717
Aggsig, AllocEncoder, Node, PrivateKey, PublicKey, PuzzleHash, Sha256Input, Sha256tree,
@@ -182,7 +182,11 @@ fn test_standard_puzzle_solution_maker() {
182182
(synthetic_public_key, (quoted_conditions_hash.clone(), ())),
183183
);
184184
let (solution, signature) =
185-
standard_solution(&mut allocator, &mut &private_key, conditions).expect("should work");
185+
standard_solution_unsafe(
186+
&mut allocator,
187+
&mut &private_key,
188+
conditions
189+
).expect("should work");
186190
let expected_full_conditions = (expected_added_condition, Node(conditions))
187191
.to_clvm(&mut allocator)
188192
.expect("should work");

0 commit comments

Comments
 (0)