@@ -3,43 +3,29 @@ use std::collections::HashMap;
33
44use crate :: {
55 constants:: { ONE_CKB , SIGHASH_TYPE_HASH } ,
6- test_util:: random_out_point,
76 tests:: {
87 build_sighash_script, init_context,
98 omni_lock:: { build_omnilock_script, build_omnilock_unlockers, OMNILOCK_BIN } ,
10- omni_lock_util:: generate_rc,
11- ACCOUNT0_ARG , ACCOUNT0_KEY , ACCOUNT1_ARG , ACCOUNT1_KEY , ACCOUNT2_ARG , ACCOUNT2_KEY ,
12- ACCOUNT3_ARG , ACCOUNT3_KEY , ALWAYS_SUCCESS_BIN , FEE_RATE , SUDT_BIN ,
9+ ACCOUNT0_ARG , ACCOUNT0_KEY , ACCOUNT1_ARG , ACCOUNT2_ARG , ACCOUNT2_KEY , ACCOUNT3_ARG ,
10+ ACCOUNT3_KEY , FEE_RATE ,
1311 } ,
14- traits:: { CellCollector , CellDepResolver , CellQueryOptions , SecpCkbRawKeySigner } ,
12+ traits:: { CellCollector , CellQueryOptions , SecpCkbRawKeySigner } ,
1513 tx_builder:: {
16- acp:: { AcpTransferBuilder , AcpTransferReceiver } ,
17- balance_tx_capacity, fill_placeholder_witnesses,
18- omni_lock:: OmniLockTransferBuilder ,
19- transfer:: { CapacityTransferBuilder , CapacityTransferBuilderWithTransaction } ,
20- udt:: { UdtTargetReceiver , UdtTransferBuilder } ,
21- CapacityProvider , TransferAction ,
14+ omni_lock:: OmniLockTransferBuilder , transfer:: CapacityTransferBuilderWithTransaction ,
2215 } ,
23- types:: xudt_rce_mol:: SmtProofEntryVec ,
2416 unlock:: {
25- omni_lock:: { AdminConfig , Identity } ,
26- opentx:: OpentxWitness ,
27- IdentityFlag , InfoCellData , MultisigConfig , OmniLockAcpConfig , OmniLockConfig ,
28- OmniLockScriptSigner , OmniLockUnlocker , OmniUnlockMode , ScriptUnlocker ,
17+ opentx:: OpentxWitness , MultisigConfig , OmniLockConfig , OmniUnlockMode , ScriptUnlocker ,
2918 SecpSighashUnlocker ,
3019 } ,
3120 util:: { blake160, keccak160} ,
32- ScriptId , Since ,
21+ ScriptId ,
3322} ;
3423
3524use ckb_crypto:: secp:: { Pubkey , SECP256K1 } ;
36- use ckb_hash:: blake2b_256;
3725use ckb_types:: {
3826 bytes:: Bytes ,
39- core:: { FeeRate , ScriptHashType } ,
40- packed:: { Byte32 , CellInput , CellOutput , Script , WitnessArgs } ,
27+ packed:: { CellOutput , WitnessArgs } ,
4128 prelude:: * ,
42- H160 , H256 ,
4329} ;
4430use rand:: Rng ;
4531
@@ -83,17 +69,16 @@ fn test_omnilock_simple_hash(mut cfg: OmniLockConfig) {
8369
8470 let output = CellOutput :: new_builder ( )
8571 . capacity ( ( 199 * ONE_CKB ) . pack ( ) )
86- . lock ( receiver . clone ( ) )
72+ . lock ( sender . clone ( ) )
8773 . build ( ) ;
8874 let builder = OmniLockTransferBuilder :: new_open (
89- ( 1 * ONE_CKB ) . into ( ) ,
75+ ONE_CKB . into ( ) ,
9076 vec ! [ ( output. clone( ) , Bytes :: default ( ) ) ] ,
9177 cfg. clone ( ) ,
9278 None ,
9379 ) ;
9480 let placeholder_witness = cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
95- let balancer =
96- CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness. clone ( ) , ZERO_FEE_RATE ) ;
81+ let balancer = CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness, ZERO_FEE_RATE ) ;
9782
9883 let mut cell_collector = ctx. to_live_cells_context ( ) ;
9984 let account0_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT0_KEY . as_bytes ( ) ) . unwrap ( ) ;
@@ -139,8 +124,7 @@ fn test_omnilock_simple_hash(mut cfg: OmniLockConfig) {
139124 let placeholder_witness = WitnessArgs :: new_builder ( )
140125 . lock ( Some ( Bytes :: from ( vec ! [ 0u8 ; 65 ] ) ) . pack ( ) )
141126 . build ( ) ;
142- let balancer =
143- CapacityBalancer :: new_simple ( receiver. clone ( ) , placeholder_witness. clone ( ) , 1000 ) ;
127+ let balancer = CapacityBalancer :: new_simple ( receiver. clone ( ) , placeholder_witness, 1000 ) ;
144128 // // Build the transaction
145129 let query = CellQueryOptions :: new_lock ( receiver. clone ( ) ) ;
146130 let ( inputs, total_capacity) = cell_collector. collect_live_cells ( & query, false ) . unwrap ( ) ;
@@ -173,13 +157,8 @@ fn test_omnilock_simple_hash(mut cfg: OmniLockConfig) {
173157 let output1 = tx. output ( 1 ) . unwrap ( ) ;
174158 assert_eq ! ( output1. lock( ) , receiver) ;
175159 let receiver_capacity: u64 = output1. capacity ( ) . unpack ( ) ;
176- assert ! ( receiver_capacity - 100 * ONE_CKB < ONE_CKB ) ;
177- let witnesses = tx
178- . witnesses ( )
179- . into_iter ( )
180- . map ( |w| w. raw_data ( ) )
181- . collect :: < Vec < _ > > ( ) ;
182- assert_eq ! ( witnesses. len( ) , 2 ) ;
160+ assert ! ( receiver_capacity - 100 * ONE_CKB < ONE_CKB ) ;
161+ assert_eq ! ( tx. witnesses( ) . len( ) , 2 ) ;
183162 ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
184163}
185164
@@ -213,17 +192,16 @@ fn test_omnilock_transfer_from_multisig() {
213192
214193 let output = CellOutput :: new_builder ( )
215194 . capacity ( ( 199 * ONE_CKB ) . pack ( ) )
216- . lock ( receiver . clone ( ) )
195+ . lock ( sender . clone ( ) )
217196 . build ( ) ;
218197 let builder = OmniLockTransferBuilder :: new_open (
219- ( 1 * ONE_CKB ) . into ( ) ,
198+ ONE_CKB . into ( ) ,
220199 vec ! [ ( output. clone( ) , Bytes :: default ( ) ) ] ,
221200 cfg. clone ( ) ,
222201 None ,
223202 ) ;
224203 let placeholder_witness = cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
225- let balancer =
226- CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness. clone ( ) , ZERO_FEE_RATE ) ;
204+ let balancer = CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness, ZERO_FEE_RATE ) ;
227205
228206 let mut cell_collector = ctx. to_live_cells_context ( ) ;
229207 let account0_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT0_KEY . as_bytes ( ) ) . unwrap ( ) ;
@@ -306,7 +284,7 @@ fn test_omnilock_transfer_from_multisig() {
306284 let output1 = tx. output ( 1 ) . unwrap ( ) ;
307285 assert_eq ! ( output1. lock( ) , receiver) ;
308286 let receiver_capacity: u64 = output1. capacity ( ) . unpack ( ) ;
309- assert ! ( receiver_capacity - 400 * ONE_CKB < ONE_CKB ) ;
287+ assert ! ( receiver_capacity - 400 * ONE_CKB < ONE_CKB ) ;
310288 let witnesses = tx
311289 . witnesses ( )
312290 . into_iter ( )
@@ -316,3 +294,173 @@ fn test_omnilock_transfer_from_multisig() {
316294 assert_eq ! ( witnesses[ 1 ] . len( ) , placeholder_witness. as_slice( ) . len( ) ) ;
317295 ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
318296}
297+
298+ #[ test]
299+ fn test_omnilock_transfer_from_sighash_absolute_from_start ( ) {
300+ test_omnilock_transfer_from_sighash_absolute ( true ) ;
301+ }
302+ #[ test]
303+ fn test_omnilock_transfer_from_sighash_absolute_self ( ) {
304+ test_omnilock_transfer_from_sighash_absolute ( false ) ;
305+ }
306+ fn test_omnilock_transfer_from_sighash_absolute ( from_start : bool ) {
307+ let cfgs: Vec < OmniLockConfig > = [ ACCOUNT0_KEY , ACCOUNT2_KEY ]
308+ . iter ( )
309+ . map ( |key| {
310+ let priv_key = secp256k1:: SecretKey :: from_slice ( key. as_bytes ( ) )
311+ . map_err ( |err| format ! ( "invalid sender secret key: {}" , err) )
312+ . unwrap ( ) ;
313+ let pubkey = secp256k1:: PublicKey :: from_secret_key ( & SECP256K1 , & priv_key) ;
314+ OmniLockConfig :: new_pubkey_hash ( blake160 ( & pubkey. serialize ( ) ) )
315+ } )
316+ . collect ( ) ;
317+ test_omnilock_simple_hash_absolute ( cfgs[ 0 ] . clone ( ) , cfgs[ 1 ] . clone ( ) , from_start) ;
318+ }
319+
320+ #[ test]
321+ fn test_omnilock_transfer_from_ethereum_absolute_from_start ( ) {
322+ test_omnilock_transfer_from_ethereum_absolute ( true ) ;
323+ }
324+ #[ test]
325+ fn test_omnilock_transfer_from_ethereum_absolute_from_self ( ) {
326+ test_omnilock_transfer_from_ethereum_absolute ( false ) ;
327+ }
328+ fn test_omnilock_transfer_from_ethereum_absolute ( from_start : bool ) {
329+ let cfgs: Vec < OmniLockConfig > = [ ACCOUNT0_KEY , ACCOUNT2_KEY ]
330+ . iter ( )
331+ . map ( |key| {
332+ let priv_key = secp256k1:: SecretKey :: from_slice ( key. as_bytes ( ) ) . unwrap ( ) ;
333+ let pubkey = secp256k1:: PublicKey :: from_secret_key ( & SECP256K1 , & priv_key) ;
334+ OmniLockConfig :: new_ethereum ( keccak160 ( Pubkey :: from ( pubkey) . as_ref ( ) ) )
335+ } )
336+ . collect ( ) ;
337+ test_omnilock_simple_hash_absolute ( cfgs[ 0 ] . clone ( ) , cfgs[ 1 ] . clone ( ) , from_start) ;
338+ }
339+
340+ /// account0(200) => account0(exchange 199) + open pay 1,
341+ /// account2(100) => account2(101 - transaction fee)
342+ fn test_omnilock_simple_hash_absolute (
343+ mut sender_cfg : OmniLockConfig ,
344+ mut receiver_cfg : OmniLockConfig ,
345+ from_start : bool ,
346+ ) {
347+ sender_cfg. set_opentx_mode ( ) ;
348+ receiver_cfg. set_opentx_mode ( ) ;
349+ let unlock_mode = OmniUnlockMode :: Normal ;
350+ let sender = build_omnilock_script ( & sender_cfg) ;
351+ let receiver = build_omnilock_script ( & receiver_cfg) ;
352+
353+ let ctx = init_context (
354+ vec ! [ ( OMNILOCK_BIN , true ) ] ,
355+ vec ! [
356+ ( sender. clone( ) , Some ( 200 * ONE_CKB ) ) ,
357+ ( receiver. clone( ) , Some ( 100 * ONE_CKB ) ) ,
358+ ( receiver. clone( ) , Some ( 200 * ONE_CKB ) ) ,
359+ ] ,
360+ ) ;
361+
362+ let output = CellOutput :: new_builder ( )
363+ . capacity ( ( 199 * ONE_CKB ) . pack ( ) )
364+ . lock ( sender. clone ( ) )
365+ . build ( ) ;
366+ let builder = OmniLockTransferBuilder :: new_open (
367+ ( ONE_CKB ) . into ( ) ,
368+ vec ! [ ( output. clone( ) , Bytes :: default ( ) ) ] ,
369+ sender_cfg. clone ( ) ,
370+ None ,
371+ ) ;
372+ let placeholder_witness = sender_cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
373+ let balancer = CapacityBalancer :: new_simple ( sender. clone ( ) , placeholder_witness, ZERO_FEE_RATE ) ;
374+
375+ let mut cell_collector = ctx. to_live_cells_context ( ) ;
376+ let account0_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT0_KEY . as_bytes ( ) ) . unwrap ( ) ;
377+ let unlockers = build_omnilock_unlockers ( account0_key, sender_cfg. clone ( ) , unlock_mode) ;
378+ let mut tx = builder
379+ . build_balanced ( & mut cell_collector, & ctx, & ctx, & ctx, & balancer, & unlockers)
380+ . unwrap ( ) ;
381+ let mut rng = rand:: thread_rng ( ) ;
382+ let salt: u32 = rng. gen ( ) ;
383+ let wit = OpentxWitness :: new_sig_all_absolute ( & tx, Some ( salt) ) . unwrap ( ) ;
384+ sender_cfg. set_opentx_input ( wit) ;
385+ tx = OmniLockTransferBuilder :: update_opentx_witness (
386+ tx,
387+ & sender_cfg,
388+ OmniUnlockMode :: Normal ,
389+ & ctx,
390+ & sender,
391+ )
392+ . unwrap ( ) ;
393+ // config updated, so unlockers must rebuilt.
394+ let unlockers = build_omnilock_unlockers ( account0_key, sender_cfg. clone ( ) , unlock_mode) ;
395+ let ( new_tx, new_locked_groups) = unlock_tx ( tx. clone ( ) , & ctx, & unlockers) . unwrap ( ) ;
396+ assert ! ( new_locked_groups. is_empty( ) ) ;
397+ tx = new_tx;
398+
399+ // use the opentx
400+ let opentx_input_len = tx. inputs ( ) . len ( ) ;
401+ let opentx_output_len = tx. outputs ( ) . len ( ) ;
402+ receiver_cfg. set_opentx_reserve_bytes_by_commands ( 20 ) ;
403+ // Build ScriptUnlocker
404+ let account2_key = secp256k1:: SecretKey :: from_slice ( ACCOUNT2_KEY . as_bytes ( ) ) . unwrap ( ) ;
405+ let unlockers = build_omnilock_unlockers ( account2_key, receiver_cfg. clone ( ) , unlock_mode) ;
406+
407+ // Build CapacityBalancer
408+ let placeholder_witness = receiver_cfg. placeholder_witness ( unlock_mode) . unwrap ( ) ;
409+ // why + 100? After update openwitness input list, will need tens of bytes more, if not +100, after update, should calculate adjust the fee again.
410+ // If adjust the transaction fee later, the exchange may mot be enough to maintain the minimal capacity.
411+ let balancer = CapacityBalancer :: new_simple ( receiver. clone ( ) , placeholder_witness, FEE_RATE ) ;
412+
413+ let builder = CapacityTransferBuilderWithTransaction :: new (
414+ vec ! [ /*(output.clone(), Bytes::default())*/ ] ,
415+ tx,
416+ ) ;
417+ let mut tx = builder
418+ . build_balanced ( & mut cell_collector, & ctx, & ctx, & ctx, & balancer, & unlockers)
419+ . unwrap ( ) ;
420+ assert_eq ! ( opentx_input_len + 1 , tx. inputs( ) . len( ) ) ;
421+ assert_eq ! ( opentx_output_len + 1 , tx. outputs( ) . len( ) ) ;
422+
423+ let mut rng = rand:: thread_rng ( ) ;
424+ let salt: u32 = rng. gen ( ) ;
425+ let mut wit = if from_start {
426+ OpentxWitness :: new_sig_all_absolute ( & tx, Some ( salt) )
427+ } else {
428+ OpentxWitness :: new_sig_to_end_absolute ( & tx, Some ( salt) , opentx_input_len, opentx_output_len)
429+ }
430+ . unwrap ( ) ; //OpentxWitness::new_sig_all_absolute(&tx, Some(salt)).unwrap();
431+ wit. add_tx_hash_input ( ) ;
432+ receiver_cfg. set_opentx_input ( wit) ;
433+
434+ tx = OmniLockTransferBuilder :: update_opentx_witness (
435+ tx,
436+ & receiver_cfg,
437+ OmniUnlockMode :: Normal ,
438+ & ctx,
439+ & receiver,
440+ )
441+ . unwrap ( ) ;
442+
443+ // config updated, so unlockers must rebuilt.
444+ let unlockers = build_omnilock_unlockers ( account2_key, receiver_cfg. clone ( ) , unlock_mode) ;
445+ let ( new_tx, new_locked_groups) = unlock_tx ( tx. clone ( ) , & ctx, & unlockers) . unwrap ( ) ;
446+
447+ assert_eq ! ( 1 , new_locked_groups. len( ) ) ;
448+ tx = new_tx;
449+
450+ println ! (
451+ "> tx: {}" ,
452+ serde_json:: to_string_pretty( & json_types:: TransactionView :: from( tx. clone( ) ) ) . unwrap( )
453+ ) ;
454+
455+ assert_eq ! ( tx. header_deps( ) . len( ) , 0 ) ;
456+ assert_eq ! ( tx. cell_deps( ) . len( ) , 1 ) ;
457+ assert_eq ! ( tx. inputs( ) . len( ) , 2 ) ;
458+ assert_eq ! ( tx. outputs( ) . len( ) , 2 ) ;
459+ assert_eq ! ( tx. output( 0 ) . unwrap( ) , output) ;
460+ let output1 = tx. output ( 1 ) . unwrap ( ) ;
461+ assert_eq ! ( output1. lock( ) , receiver) ;
462+ let receiver_capacity: u64 = output1. capacity ( ) . unpack ( ) ;
463+ assert ! ( receiver_capacity - 100 * ONE_CKB < ONE_CKB ) ;
464+ assert_eq ! ( tx. witnesses( ) . len( ) , 2 ) ;
465+ ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
466+ }
0 commit comments