@@ -6,8 +6,8 @@ use crate::{
66 tests:: {
77 build_sighash_script, init_context,
88 omni_lock:: { build_omnilock_script, build_omnilock_unlockers, OMNILOCK_BIN } ,
9- ACCOUNT0_ARG , ACCOUNT0_KEY , ACCOUNT1_ARG , ACCOUNT2_ARG , ACCOUNT2_KEY , ACCOUNT3_ARG ,
10- ACCOUNT3_KEY , FEE_RATE ,
9+ ACCOUNT0_ARG , ACCOUNT0_KEY , ACCOUNT1_ARG , ACCOUNT1_KEY , ACCOUNT2_ARG , ACCOUNT2_KEY ,
10+ ACCOUNT3_ARG , ACCOUNT3_KEY , FEE_RATE ,
1111 } ,
1212 traits:: { CellCollector , CellQueryOptions , SecpCkbRawKeySigner } ,
1313 tx_builder:: {
@@ -420,7 +420,6 @@ fn test_omnilock_simple_hash_absolute(
420420 assert_eq ! ( opentx_input_len + 1 , tx. inputs( ) . len( ) ) ;
421421 assert_eq ! ( opentx_output_len + 1 , tx. outputs( ) . len( ) ) ;
422422
423- let mut rng = rand:: thread_rng ( ) ;
424423 let salt: u32 = rng. gen ( ) ;
425424 let mut wit = if from_start {
426425 OpentxWitness :: new_sig_all_absolute ( & tx, Some ( salt) )
@@ -464,3 +463,153 @@ fn test_omnilock_simple_hash_absolute(
464463 assert_eq ! ( tx. witnesses( ) . len( ) , 2 ) ;
465464 ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
466465}
466+ #[ test]
467+ fn test_omnilock_transfer_from_multisig_absolute_from_start ( ) {
468+ test_omnilock_transfer_from_multisig_absolute ( true ) ;
469+ }
470+
471+ #[ test]
472+ fn test_omnilock_transfer_from_multisig_absolute_from_self ( ) {
473+ test_omnilock_transfer_from_multisig_absolute ( false ) ;
474+ }
475+
476+ /// multisig(200) => multisig(exchange 199) + open pay 1, locked by account0, account1, account2
477+ /// account3(400) => account2(401 - transaction fee)
478+ fn test_omnilock_transfer_from_multisig_absolute ( from_start : bool ) {
479+ let unlock_mode = OmniUnlockMode :: Normal ;
480+ let lock_args = vec ! [
481+ ACCOUNT0_ARG . clone( ) ,
482+ ACCOUNT1_ARG . clone( ) ,
483+ ACCOUNT2_ARG . clone( ) ,
484+ ] ;
485+ let multi_cfg = MultisigConfig :: new_with ( lock_args, 0 , 2 ) . unwrap ( ) ;
486+ let mut sender_cfg = OmniLockConfig :: new_multisig ( multi_cfg) ;
487+ sender_cfg. set_opentx_mode ( ) ;
488+
489+ let sender = build_omnilock_script ( & sender_cfg) ;
490+ let lock_args = vec ! [
491+ ACCOUNT1_ARG . clone( ) ,
492+ ACCOUNT2_ARG . clone( ) ,
493+ ACCOUNT3_ARG . clone( ) ,
494+ ] ;
495+ let multi_cfg = MultisigConfig :: new_with ( lock_args, 0 , 2 ) . unwrap ( ) ;
496+ let mut receiver_cfg = OmniLockConfig :: new_multisig ( multi_cfg) ;
497+ receiver_cfg. set_opentx_mode ( ) ;
498+ let receiver = build_omnilock_script ( & receiver_cfg) ;
499+
500+ let ctx = init_context (
501+ vec ! [ ( OMNILOCK_BIN , true ) ] ,
502+ vec ! [
503+ ( sender. clone( ) , Some ( 200 * ONE_CKB ) ) ,
504+ ( sender. clone( ) , Some ( 300 * ONE_CKB ) ) ,
505+ ( receiver. clone( ) , Some ( 400 * ONE_CKB ) ) ,
506+ ( receiver. clone( ) , Some ( 500 * ONE_CKB ) ) ,
507+ ( receiver. clone( ) , Some ( 600 * ONE_CKB ) ) ,
508+ ] ,
509+ ) ;
510+
511+ let output = CellOutput :: new_builder ( )
512+ . capacity ( ( 199 * ONE_CKB ) . pack ( ) )
513+ . lock ( sender. clone ( ) )
514+ . build ( ) ;
515+ let builder = OmniLockTransferBuilder :: new_open (
516+ ONE_CKB . into ( ) ,
517+ vec ! [ ( output. clone( ) , Bytes :: default ( ) ) ] ,
518+ sender_cfg. clone ( ) ,
519+ None ,
520+ ) ;
521+ let placeholder_witness = sender_cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
522+ let balancer = CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness, ZERO_FEE_RATE ) ;
523+
524+ let mut cell_collector = ctx. to_live_cells_context ( ) ;
525+ let account0_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT0_KEY . as_bytes ( ) ) . unwrap ( ) ;
526+ let account2_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT2_KEY . as_bytes ( ) ) . unwrap ( ) ;
527+ let unlockers = build_omnilock_unlockers ( account0_key, sender_cfg. clone ( ) , unlock_mode) ;
528+ let mut tx = builder
529+ . build_balanced ( & mut cell_collector, & ctx, & ctx, & ctx, & balancer, & unlockers)
530+ . unwrap ( ) ;
531+ // add opentx hash data
532+ let mut rng = rand:: thread_rng ( ) ;
533+ let salt: u32 = rng. gen ( ) ;
534+ let wit = OpentxWitness :: new_sig_all_absolute ( & tx, Some ( salt) ) . unwrap ( ) ;
535+ sender_cfg. set_opentx_input ( wit) ;
536+ tx = OmniLockTransferBuilder :: update_opentx_witness (
537+ tx,
538+ & sender_cfg,
539+ OmniUnlockMode :: Normal ,
540+ & ctx,
541+ & sender,
542+ )
543+ . unwrap ( ) ;
544+ for key in [ account0_key, account2_key] {
545+ let unlockers = build_omnilock_unlockers ( key, sender_cfg. clone ( ) , unlock_mode) ;
546+ let ( new_tx, new_locked_groups) = unlock_tx ( tx. clone ( ) , & ctx, & unlockers) . unwrap ( ) ;
547+ assert ! ( new_locked_groups. is_empty( ) ) ;
548+ tx = new_tx;
549+ }
550+
551+ println ! (
552+ "> tx: {}" ,
553+ serde_json:: to_string_pretty( & json_types:: TransactionView :: from( tx. clone( ) ) ) . unwrap( )
554+ ) ;
555+ // use the opentx
556+ let opentx_input_len = tx. inputs ( ) . len ( ) ;
557+ let opentx_output_len = tx. outputs ( ) . len ( ) ;
558+ receiver_cfg. set_opentx_reserve_bytes_by_commands ( 20 ) ;
559+ // Build ScriptUnlocker
560+ let account1_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT1_KEY . as_bytes ( ) ) . unwrap ( ) ;
561+ let account3_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT3_KEY . as_bytes ( ) ) . unwrap ( ) ;
562+ let unlockers = build_omnilock_unlockers ( account1_key, receiver_cfg. clone ( ) , unlock_mode) ;
563+ // Build CapacityBalancer
564+ let placeholder_witness = receiver_cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
565+ let balancer = CapacityBalancer :: new_simple ( receiver. clone ( ) , placeholder_witness, FEE_RATE ) ;
566+
567+ let builder = CapacityTransferBuilderWithTransaction :: new ( vec ! [ ] , tx) ;
568+ let mut tx = builder
569+ . build_balanced ( & mut cell_collector, & ctx, & ctx, & ctx, & balancer, & unlockers)
570+ . unwrap ( ) ;
571+ assert_eq ! ( opentx_input_len + 1 , tx. inputs( ) . len( ) ) ;
572+ assert_eq ! ( opentx_output_len + 1 , tx. outputs( ) . len( ) ) ;
573+
574+ let salt: u32 = rng. gen ( ) ;
575+ let mut wit = if from_start {
576+ OpentxWitness :: new_sig_all_absolute ( & tx, Some ( salt) )
577+ } else {
578+ OpentxWitness :: new_sig_to_end_absolute ( & tx, Some ( salt) , opentx_input_len, opentx_output_len)
579+ }
580+ . unwrap ( ) ; //OpentxWitness::new_sig_all_absolute(&tx, Some(salt)).unwrap();
581+ wit. add_tx_hash_input ( ) ;
582+ receiver_cfg. set_opentx_input ( wit) ;
583+
584+ tx = OmniLockTransferBuilder :: update_opentx_witness (
585+ tx,
586+ & receiver_cfg,
587+ OmniUnlockMode :: Normal ,
588+ & ctx,
589+ & receiver,
590+ )
591+ . unwrap ( ) ;
592+
593+ for key in [ account1_key, account3_key] {
594+ let unlockers = build_omnilock_unlockers ( key, receiver_cfg. clone ( ) , unlock_mode) ;
595+ let ( new_tx, new_locked_groups) = unlock_tx ( tx. clone ( ) , & ctx, & unlockers) . unwrap ( ) ;
596+ assert_eq ! ( 1 , new_locked_groups. len( ) ) ;
597+ tx = new_tx;
598+ }
599+ println ! (
600+ "> tx: {}" ,
601+ serde_json:: to_string_pretty( & json_types:: TransactionView :: from( tx. clone( ) ) ) . unwrap( )
602+ ) ;
603+ assert_eq ! ( tx. header_deps( ) . len( ) , 0 ) ;
604+ assert_eq ! ( tx. cell_deps( ) . len( ) , 1 ) ;
605+ assert_eq ! ( tx. inputs( ) . len( ) , 2 ) ;
606+ assert_eq ! ( tx. outputs( ) . len( ) , 2 ) ;
607+ assert_eq ! ( tx. output( 0 ) . unwrap( ) , output) ;
608+ let output1 = tx. output ( 1 ) . unwrap ( ) ;
609+ assert_eq ! ( output1. lock( ) , receiver) ;
610+ let receiver_capacity: u64 = output1. capacity ( ) . unpack ( ) ;
611+ assert ! ( receiver_capacity - 400 * ONE_CKB < ONE_CKB ) ;
612+
613+ assert_eq ! ( tx. witnesses( ) . len( ) , 2 ) ;
614+ ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
615+ }
0 commit comments