Skip to content

Commit

Permalink
test: 💍 Add test about multisig opentx test case
Browse files Browse the repository at this point in the history
  • Loading branch information
Liu Chuankai committed Nov 7, 2022
1 parent ede9cdd commit ec997b1
Showing 1 changed file with 152 additions and 3 deletions.
155 changes: 152 additions & 3 deletions src/tests/opentx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{
tests::{
build_sighash_script, init_context,
omni_lock::{build_omnilock_script, build_omnilock_unlockers, OMNILOCK_BIN},
ACCOUNT0_ARG, ACCOUNT0_KEY, ACCOUNT1_ARG, ACCOUNT2_ARG, ACCOUNT2_KEY, ACCOUNT3_ARG,
ACCOUNT3_KEY, FEE_RATE,
ACCOUNT0_ARG, ACCOUNT0_KEY, ACCOUNT1_ARG, ACCOUNT1_KEY, ACCOUNT2_ARG, ACCOUNT2_KEY,
ACCOUNT3_ARG, ACCOUNT3_KEY, FEE_RATE,
},
traits::{CellCollector, CellQueryOptions, SecpCkbRawKeySigner},
tx_builder::{
Expand Down Expand Up @@ -420,7 +420,6 @@ fn test_omnilock_simple_hash_absolute(
assert_eq!(opentx_input_len + 1, tx.inputs().len());
assert_eq!(opentx_output_len + 1, tx.outputs().len());

let mut rng = rand::thread_rng();
let salt: u32 = rng.gen();
let mut wit = if from_start {
OpentxWitness::new_sig_all_absolute(&tx, Some(salt))
Expand Down Expand Up @@ -464,3 +463,153 @@ fn test_omnilock_simple_hash_absolute(
assert_eq!(tx.witnesses().len(), 2);
ctx.verify(tx, FEE_RATE).unwrap();
}
#[test]
fn test_omnilock_transfer_from_multisig_absolute_from_start() {
test_omnilock_transfer_from_multisig_absolute(true);
}

#[test]
fn test_omnilock_transfer_from_multisig_absolute_from_self() {
test_omnilock_transfer_from_multisig_absolute(false);
}

/// multisig(200) => multisig(exchange 199) + open pay 1, locked by account0, account1, account2
/// account3(400) => account2(401 - transaction fee)
fn test_omnilock_transfer_from_multisig_absolute(from_start: bool) {
let unlock_mode = OmniUnlockMode::Normal;
let lock_args = vec![
ACCOUNT0_ARG.clone(),
ACCOUNT1_ARG.clone(),
ACCOUNT2_ARG.clone(),
];
let multi_cfg = MultisigConfig::new_with(lock_args, 0, 2).unwrap();
let mut sender_cfg = OmniLockConfig::new_multisig(multi_cfg);
sender_cfg.set_opentx_mode();

let sender = build_omnilock_script(&sender_cfg);
let lock_args = vec![
ACCOUNT1_ARG.clone(),
ACCOUNT2_ARG.clone(),
ACCOUNT3_ARG.clone(),
];
let multi_cfg = MultisigConfig::new_with(lock_args, 0, 2).unwrap();
let mut receiver_cfg = OmniLockConfig::new_multisig(multi_cfg);
receiver_cfg.set_opentx_mode();
let receiver = build_omnilock_script(&receiver_cfg);

let ctx = init_context(
vec![(OMNILOCK_BIN, true)],
vec![
(sender.clone(), Some(200 * ONE_CKB)),
(sender.clone(), Some(300 * ONE_CKB)),
(receiver.clone(), Some(400 * ONE_CKB)),
(receiver.clone(), Some(500 * ONE_CKB)),
(receiver.clone(), Some(600 * ONE_CKB)),
],
);

let output = CellOutput::new_builder()
.capacity((199 * ONE_CKB).pack())
.lock(sender.clone())
.build();
let builder = OmniLockTransferBuilder::new_open(
ONE_CKB.into(),
vec![(output.clone(), Bytes::default())],
sender_cfg.clone(),
None,
);
let placeholder_witness = sender_cfg.placeholder_witness(unlock_mode).unwrap();
let balancer = CapacityBalancer::new_simple(sender.clone(), placeholder_witness, ZERO_FEE_RATE);

let mut cell_collector = ctx.to_live_cells_context();
let account0_key = secp256k1::SecretKey::from_slice(ACCOUNT0_KEY.as_bytes()).unwrap();
let account2_key = secp256k1::SecretKey::from_slice(ACCOUNT2_KEY.as_bytes()).unwrap();
let unlockers = build_omnilock_unlockers(account0_key, sender_cfg.clone(), unlock_mode);
let mut tx = builder
.build_balanced(&mut cell_collector, &ctx, &ctx, &ctx, &balancer, &unlockers)
.unwrap();
// add opentx hash data
let mut rng = rand::thread_rng();
let salt: u32 = rng.gen();
let wit = OpentxWitness::new_sig_all_absolute(&tx, Some(salt)).unwrap();
sender_cfg.set_opentx_input(wit);
tx = OmniLockTransferBuilder::update_opentx_witness(
tx,
&sender_cfg,
OmniUnlockMode::Normal,
&ctx,
&sender,
)
.unwrap();
for key in [account0_key, account2_key] {
let unlockers = build_omnilock_unlockers(key, sender_cfg.clone(), unlock_mode);
let (new_tx, new_locked_groups) = unlock_tx(tx.clone(), &ctx, &unlockers).unwrap();
assert!(new_locked_groups.is_empty());
tx = new_tx;
}

println!(
"> tx: {}",
serde_json::to_string_pretty(&json_types::TransactionView::from(tx.clone())).unwrap()
);
// use the opentx
let opentx_input_len = tx.inputs().len();
let opentx_output_len = tx.outputs().len();
receiver_cfg.set_opentx_reserve_bytes_by_commands(20);
// Build ScriptUnlocker
let account1_key = secp256k1::SecretKey::from_slice(ACCOUNT1_KEY.as_bytes()).unwrap();
let account3_key = secp256k1::SecretKey::from_slice(ACCOUNT3_KEY.as_bytes()).unwrap();
let unlockers = build_omnilock_unlockers(account1_key, receiver_cfg.clone(), unlock_mode);
// Build CapacityBalancer
let placeholder_witness = receiver_cfg.placeholder_witness(unlock_mode).unwrap();
let balancer = CapacityBalancer::new_simple(receiver.clone(), placeholder_witness, FEE_RATE);

let builder = CapacityTransferBuilderWithTransaction::new(vec![], tx);
let mut tx = builder
.build_balanced(&mut cell_collector, &ctx, &ctx, &ctx, &balancer, &unlockers)
.unwrap();
assert_eq!(opentx_input_len + 1, tx.inputs().len());
assert_eq!(opentx_output_len + 1, tx.outputs().len());

let salt: u32 = rng.gen();
let mut wit = if from_start {
OpentxWitness::new_sig_all_absolute(&tx, Some(salt))
} else {
OpentxWitness::new_sig_to_end_absolute(&tx, Some(salt), opentx_input_len, opentx_output_len)
}
.unwrap(); //OpentxWitness::new_sig_all_absolute(&tx, Some(salt)).unwrap();
wit.add_tx_hash_input();
receiver_cfg.set_opentx_input(wit);

tx = OmniLockTransferBuilder::update_opentx_witness(
tx,
&receiver_cfg,
OmniUnlockMode::Normal,
&ctx,
&receiver,
)
.unwrap();

for key in [account1_key, account3_key] {
let unlockers = build_omnilock_unlockers(key, receiver_cfg.clone(), unlock_mode);
let (new_tx, new_locked_groups) = unlock_tx(tx.clone(), &ctx, &unlockers).unwrap();
assert_eq!(1, new_locked_groups.len());
tx = new_tx;
}
println!(
"> tx: {}",
serde_json::to_string_pretty(&json_types::TransactionView::from(tx.clone())).unwrap()
);
assert_eq!(tx.header_deps().len(), 0);
assert_eq!(tx.cell_deps().len(), 1);
assert_eq!(tx.inputs().len(), 2);
assert_eq!(tx.outputs().len(), 2);
assert_eq!(tx.output(0).unwrap(), output);
let output1 = tx.output(1).unwrap();
assert_eq!(output1.lock(), receiver);
let receiver_capacity: u64 = output1.capacity().unpack();
assert!(receiver_capacity - 400 * ONE_CKB < ONE_CKB);

assert_eq!(tx.witnesses().len(), 2);
ctx.verify(tx, FEE_RATE).unwrap();
}

0 comments on commit ec997b1

Please sign in to comment.