@@ -22,7 +22,9 @@ use common::address::pubkeyhash::PublicKeyHash;
22
22
use common:: chain:: block:: timestamp:: BlockTimestamp ;
23
23
use common:: chain:: classic_multisig:: ClassicMultisigChallenge ;
24
24
use common:: chain:: htlc:: HashedTimelockContract ;
25
- use common:: chain:: { AccountCommand , AccountOutPoint , AccountSpending , OrderId , RpcOrderInfo } ;
25
+ use common:: chain:: {
26
+ AccountCommand , AccountOutPoint , AccountSpending , OrderAccountCommand , OrderId , RpcOrderInfo ,
27
+ } ;
26
28
use common:: primitives:: id:: WithId ;
27
29
use common:: primitives:: { Idable , H256 } ;
28
30
use common:: size_estimation:: {
@@ -981,14 +983,35 @@ impl<K: AccountKeyChains> Account<K> {
981
983
outputs. push ( TxOutput :: Transfer ( output_value, output_destination) ) ;
982
984
}
983
985
984
- let nonce = order_info
985
- . nonce
986
- . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
987
- . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
988
- let request = SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
989
- TxInput :: AccountCommand ( nonce, AccountCommand :: ConcludeOrder ( order_id) ) ,
990
- order_info. conclude_key . clone ( ) ,
991
- ) ] ) ;
986
+ let version = self
987
+ . chain_config
988
+ . chainstate_upgrades ( )
989
+ . version_at_height ( self . account_info . best_block_height ( ) )
990
+ . 1
991
+ . orders_version ( ) ;
992
+
993
+ let request = match version {
994
+ common:: chain:: OrdersVersion :: V0 => {
995
+ let nonce = order_info
996
+ . nonce
997
+ . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
998
+ . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
999
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1000
+ TxInput :: AccountCommand ( nonce, AccountCommand :: ConcludeOrder ( order_id) ) ,
1001
+ order_info. conclude_key . clone ( ) ,
1002
+ ) ] )
1003
+ }
1004
+ common:: chain:: OrdersVersion :: V1 => {
1005
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1006
+ TxInput :: OrderAccountCommand ( OrderAccountCommand :: ConcludeOrder {
1007
+ order_id,
1008
+ filled_amount,
1009
+ remaining_give_amount : order_info. give_balance ,
1010
+ } ) ,
1011
+ order_info. conclude_key . clone ( ) ,
1012
+ ) ] )
1013
+ }
1014
+ } ;
992
1015
993
1016
self . select_inputs_for_send_request (
994
1017
request,
@@ -1019,33 +1042,66 @@ impl<K: AccountKeyChains> Account<K> {
1019
1042
self . get_new_address ( db_tx, KeyPurpose :: ReceiveFunds ) ?. 1 . into_object ( )
1020
1043
} ;
1021
1044
1022
- let filled_amount = orders_accounting:: calculate_filled_amount (
1023
- order_info. ask_balance ,
1024
- order_info. give_balance ,
1025
- fill_amount_in_ask_currency,
1026
- )
1027
- . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1028
- let output_value = match order_info. initially_given {
1029
- RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1030
- RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1031
- } ;
1032
- let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1033
-
1034
- let nonce = order_info
1035
- . nonce
1036
- . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1037
- . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1038
- let request = SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1039
- TxInput :: AccountCommand (
1040
- nonce,
1041
- AccountCommand :: FillOrder (
1042
- order_id,
1045
+ let version = self
1046
+ . chain_config
1047
+ . chainstate_upgrades ( )
1048
+ . version_at_height ( self . account_info . best_block_height ( ) )
1049
+ . 1
1050
+ . orders_version ( ) ;
1051
+
1052
+ let request = match version {
1053
+ common:: chain:: OrdersVersion :: V0 => {
1054
+ let filled_amount = orders_accounting:: calculate_filled_amount (
1055
+ order_info. ask_balance ,
1056
+ order_info. give_balance ,
1043
1057
fill_amount_in_ask_currency,
1044
- output_destination. clone ( ) ,
1045
- ) ,
1046
- ) ,
1047
- output_destination,
1048
- ) ] ) ;
1058
+ )
1059
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1060
+ let output_value = match order_info. initially_given {
1061
+ RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1062
+ RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1063
+ } ;
1064
+ let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1065
+
1066
+ let nonce = order_info
1067
+ . nonce
1068
+ . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1069
+ . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1070
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1071
+ TxInput :: AccountCommand (
1072
+ nonce,
1073
+ AccountCommand :: FillOrder (
1074
+ order_id,
1075
+ fill_amount_in_ask_currency,
1076
+ output_destination. clone ( ) ,
1077
+ ) ,
1078
+ ) ,
1079
+ output_destination,
1080
+ ) ] )
1081
+ }
1082
+ common:: chain:: OrdersVersion :: V1 => {
1083
+ let filled_amount = orders_accounting:: calculate_filled_amount (
1084
+ order_info. initially_asked . amount ( ) ,
1085
+ order_info. initially_given . amount ( ) ,
1086
+ fill_amount_in_ask_currency,
1087
+ )
1088
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1089
+ let output_value = match order_info. initially_given {
1090
+ RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1091
+ RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1092
+ } ;
1093
+ let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1094
+
1095
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1096
+ TxInput :: OrderAccountCommand ( OrderAccountCommand :: FillOrder (
1097
+ order_id,
1098
+ fill_amount_in_ask_currency,
1099
+ output_destination. clone ( ) ,
1100
+ ) ) ,
1101
+ output_destination,
1102
+ ) ] )
1103
+ }
1104
+ } ;
1049
1105
1050
1106
self . select_inputs_for_send_request (
1051
1107
request,
@@ -1470,6 +1526,24 @@ impl<K: AccountKeyChains> Account<K> {
1470
1526
}
1471
1527
}
1472
1528
1529
+ pub fn find_order_account_command_destination (
1530
+ & self ,
1531
+ cmd : & OrderAccountCommand ,
1532
+ ) -> WalletResult < Destination > {
1533
+ match cmd {
1534
+ OrderAccountCommand :: FillOrder ( _, _, destination) => Ok ( destination. clone ( ) ) ,
1535
+ OrderAccountCommand :: ConcludeOrder {
1536
+ order_id,
1537
+ filled_amount : _,
1538
+ remaining_give_amount : _,
1539
+ } => self
1540
+ . output_cache
1541
+ . order_data ( order_id)
1542
+ . map ( |data| data. conclude_key . clone ( ) )
1543
+ . ok_or ( WalletError :: UnknownOrderId ( * order_id) ) ,
1544
+ }
1545
+ }
1546
+
1473
1547
pub fn find_unspent_utxo_and_destination (
1474
1548
& self ,
1475
1549
outpoint : & UtxoOutPoint ,
@@ -1902,10 +1976,16 @@ impl<K: AccountKeyChains> Account<K> {
1902
1976
self . find_delegation ( delegation_id) . is_ok ( )
1903
1977
}
1904
1978
} ,
1905
- TxInput :: OrderAccountCommand ( ..) => {
1906
- // TODO: support OrdersVersion::V1
1907
- unimplemented ! ( )
1908
- }
1979
+ TxInput :: OrderAccountCommand ( cmd) => match cmd {
1980
+ OrderAccountCommand :: FillOrder ( order_id, _, dest) => {
1981
+ self . find_order ( order_id) . is_ok ( ) || self . is_destination_mine_or_watched ( dest)
1982
+ }
1983
+ OrderAccountCommand :: ConcludeOrder {
1984
+ order_id,
1985
+ filled_amount : _,
1986
+ remaining_give_amount : _,
1987
+ } => self . find_order ( order_id) . is_ok ( ) ,
1988
+ } ,
1909
1989
TxInput :: AccountCommand ( _, op) => match op {
1910
1990
AccountCommand :: MintTokens ( token_id, _)
1911
1991
| AccountCommand :: UnmintTokens ( token_id)
@@ -2408,9 +2488,6 @@ fn group_preselected_inputs(
2408
2488
update_preselected_inputs ( Currency :: Coin , * amount, * fee, Amount :: ZERO ) ?;
2409
2489
}
2410
2490
} ,
2411
- TxInput :: OrderAccountCommand ( ..) => {
2412
- // TODO: support OrdersVersion::V1
2413
- }
2414
2491
TxInput :: AccountCommand ( _, op) => match op {
2415
2492
AccountCommand :: MintTokens ( token_id, amount) => {
2416
2493
update_preselected_inputs (
@@ -2460,59 +2537,43 @@ fn group_preselected_inputs(
2460
2537
) ?;
2461
2538
}
2462
2539
AccountCommand :: ConcludeOrder ( order_id) => {
2463
- let order_info = order_info
2464
- . as_ref ( )
2465
- . and_then ( |info| info. get ( order_id) )
2466
- . ok_or ( WalletError :: OrderInfoMissing ( * order_id) ) ?;
2467
-
2468
- let given_currency =
2469
- Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2470
- update_preselected_inputs (
2471
- given_currency,
2472
- order_info. give_balance ,
2473
- Amount :: ZERO ,
2474
- Amount :: ZERO ,
2540
+ handle_conclude_order (
2541
+ * order_id,
2542
+ order_info. as_ref ( ) ,
2543
+ * fee,
2544
+ & mut update_preselected_inputs,
2475
2545
) ?;
2476
-
2477
- let asked_currency =
2478
- Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2479
- let filled_amount = ( order_info. initially_asked . amount ( )
2480
- - order_info. ask_balance )
2481
- . ok_or ( WalletError :: OutputAmountOverflow ) ?;
2482
- update_preselected_inputs (
2483
- asked_currency,
2484
- filled_amount,
2485
- Amount :: ZERO ,
2486
- Amount :: ZERO ,
2487
- ) ?;
2488
-
2489
- // add fee
2490
- update_preselected_inputs ( Currency :: Coin , Amount :: ZERO , * fee, Amount :: ZERO ) ?;
2491
2546
}
2492
2547
AccountCommand :: FillOrder ( order_id, fill_amount_in_ask_currency, _) => {
2493
- let order_info = order_info
2494
- . as_ref ( )
2495
- . and_then ( |info| info. get ( order_id) )
2496
- . ok_or ( WalletError :: OrderInfoMissing ( * order_id) ) ?;
2497
-
2498
- let filled_amount = orders_accounting:: calculate_filled_amount (
2499
- order_info. ask_balance ,
2500
- order_info. give_balance ,
2501
- * fill_amount_in_ask_currency,
2502
- )
2503
- . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( * order_id) ) ?;
2504
-
2505
- let given_currency =
2506
- Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2507
- update_preselected_inputs ( given_currency, filled_amount, * fee, Amount :: ZERO ) ?;
2508
-
2509
- let asked_currency =
2510
- Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2511
- update_preselected_inputs (
2512
- asked_currency,
2513
- Amount :: ZERO ,
2514
- Amount :: ZERO ,
2548
+ handle_fill_order_op (
2549
+ * order_id,
2515
2550
* fill_amount_in_ask_currency,
2551
+ order_info. as_ref ( ) ,
2552
+ * fee,
2553
+ & mut update_preselected_inputs,
2554
+ ) ?;
2555
+ }
2556
+ } ,
2557
+ TxInput :: OrderAccountCommand ( cmd) => match cmd {
2558
+ OrderAccountCommand :: FillOrder ( id, amount, _) => {
2559
+ handle_fill_order_op (
2560
+ * id,
2561
+ * amount,
2562
+ order_info. as_ref ( ) ,
2563
+ * fee,
2564
+ & mut update_preselected_inputs,
2565
+ ) ?;
2566
+ }
2567
+ OrderAccountCommand :: ConcludeOrder {
2568
+ order_id,
2569
+ filled_amount : _,
2570
+ remaining_give_amount : _,
2571
+ } => {
2572
+ handle_conclude_order (
2573
+ * order_id,
2574
+ order_info. as_ref ( ) ,
2575
+ * fee,
2576
+ & mut update_preselected_inputs,
2516
2577
) ?;
2517
2578
}
2518
2579
} ,
@@ -2521,6 +2582,67 @@ fn group_preselected_inputs(
2521
2582
Ok ( preselected_inputs)
2522
2583
}
2523
2584
2585
+ fn handle_fill_order_op (
2586
+ order_id : OrderId ,
2587
+ fill_amount_in_ask_currency : Amount ,
2588
+ order_info : Option < & BTreeMap < OrderId , & RpcOrderInfo > > ,
2589
+ fee : Amount ,
2590
+ update_preselected_inputs : & mut impl FnMut ( Currency , Amount , Amount , Amount ) -> WalletResult < ( ) > ,
2591
+ ) -> WalletResult < ( ) > {
2592
+ let order_info = order_info
2593
+ . as_ref ( )
2594
+ . and_then ( |info| info. get ( & order_id) )
2595
+ . ok_or ( WalletError :: OrderInfoMissing ( order_id) ) ?;
2596
+
2597
+ let filled_amount = orders_accounting:: calculate_filled_amount (
2598
+ order_info. ask_balance ,
2599
+ order_info. give_balance ,
2600
+ fill_amount_in_ask_currency,
2601
+ )
2602
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
2603
+
2604
+ let given_currency = Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2605
+ update_preselected_inputs ( given_currency, filled_amount, fee, Amount :: ZERO ) ?;
2606
+
2607
+ let asked_currency = Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2608
+ update_preselected_inputs (
2609
+ asked_currency,
2610
+ Amount :: ZERO ,
2611
+ Amount :: ZERO ,
2612
+ fill_amount_in_ask_currency,
2613
+ ) ?;
2614
+ Ok ( ( ) )
2615
+ }
2616
+
2617
+ fn handle_conclude_order (
2618
+ order_id : OrderId ,
2619
+ order_info : Option < & BTreeMap < OrderId , & RpcOrderInfo > > ,
2620
+ fee : Amount ,
2621
+ update_preselected_inputs : & mut impl FnMut ( Currency , Amount , Amount , Amount ) -> WalletResult < ( ) > ,
2622
+ ) -> WalletResult < ( ) > {
2623
+ let order_info = order_info
2624
+ . as_ref ( )
2625
+ . and_then ( |info| info. get ( & order_id) )
2626
+ . ok_or ( WalletError :: OrderInfoMissing ( order_id) ) ?;
2627
+
2628
+ let given_currency = Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2629
+ update_preselected_inputs (
2630
+ given_currency,
2631
+ order_info. give_balance ,
2632
+ Amount :: ZERO ,
2633
+ Amount :: ZERO ,
2634
+ ) ?;
2635
+
2636
+ let asked_currency = Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2637
+ let filled_amount = ( order_info. initially_asked . amount ( ) - order_info. ask_balance )
2638
+ . ok_or ( WalletError :: OutputAmountOverflow ) ?;
2639
+ update_preselected_inputs ( asked_currency, filled_amount, Amount :: ZERO , Amount :: ZERO ) ?;
2640
+
2641
+ // add fee
2642
+ update_preselected_inputs ( Currency :: Coin , Amount :: ZERO , fee, Amount :: ZERO ) ?;
2643
+ Ok ( ( ) )
2644
+ }
2645
+
2524
2646
/// Calculate the amount of fee that needs to be paid to add a change output
2525
2647
/// Returns the Amounts for Coin output and Token output
2526
2648
fn coin_and_token_output_change_fees (
0 commit comments