@@ -23,7 +23,9 @@ use common::chain::block::timestamp::BlockTimestamp;
23
23
use common:: chain:: classic_multisig:: ClassicMultisigChallenge ;
24
24
use common:: chain:: htlc:: HashedTimelockContract ;
25
25
use common:: chain:: partially_signed_transaction:: PartiallySignedTransaction ;
26
- use common:: chain:: { AccountCommand , AccountOutPoint , AccountSpending , OrderId , RpcOrderInfo } ;
26
+ use common:: chain:: {
27
+ AccountCommand , AccountOutPoint , AccountSpending , OrderAccountCommand , OrderId , RpcOrderInfo ,
28
+ } ;
27
29
use common:: primitives:: id:: WithId ;
28
30
use common:: primitives:: { Idable , H256 } ;
29
31
use common:: size_estimation:: {
@@ -1084,14 +1086,35 @@ impl Account {
1084
1086
outputs. push ( TxOutput :: Transfer ( output_value, output_destination) ) ;
1085
1087
}
1086
1088
1087
- let nonce = order_info
1088
- . nonce
1089
- . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1090
- . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1091
- let request = SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1092
- TxInput :: AccountCommand ( nonce, AccountCommand :: ConcludeOrder ( order_id) ) ,
1093
- order_info. conclude_key . clone ( ) ,
1094
- ) ] ) ;
1089
+ let version = self
1090
+ . chain_config
1091
+ . chainstate_upgrades ( )
1092
+ . version_at_height ( self . account_info . best_block_height ( ) )
1093
+ . 1
1094
+ . orders_version ( ) ;
1095
+
1096
+ let request = match version {
1097
+ common:: chain:: OrdersVersion :: V0 => {
1098
+ let nonce = order_info
1099
+ . nonce
1100
+ . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1101
+ . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1102
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1103
+ TxInput :: AccountCommand ( nonce, AccountCommand :: ConcludeOrder ( order_id) ) ,
1104
+ order_info. conclude_key . clone ( ) ,
1105
+ ) ] )
1106
+ }
1107
+ common:: chain:: OrdersVersion :: V1 => {
1108
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1109
+ TxInput :: OrderAccountCommand ( OrderAccountCommand :: ConcludeOrder {
1110
+ order_id,
1111
+ filled_amount,
1112
+ remaining_give_amount : order_info. give_balance ,
1113
+ } ) ,
1114
+ order_info. conclude_key . clone ( ) ,
1115
+ ) ] )
1116
+ }
1117
+ } ;
1095
1118
1096
1119
self . select_inputs_for_send_request (
1097
1120
request,
@@ -1122,33 +1145,66 @@ impl Account {
1122
1145
self . get_new_address ( db_tx, KeyPurpose :: ReceiveFunds ) ?. 1 . into_object ( )
1123
1146
} ;
1124
1147
1125
- let filled_amount = orders_accounting:: calculate_filled_amount (
1126
- order_info. ask_balance ,
1127
- order_info. give_balance ,
1128
- fill_amount_in_ask_currency,
1129
- )
1130
- . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1131
- let output_value = match order_info. initially_given {
1132
- RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1133
- RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1134
- } ;
1135
- let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1136
-
1137
- let nonce = order_info
1138
- . nonce
1139
- . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1140
- . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1141
- let request = SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1142
- TxInput :: AccountCommand (
1143
- nonce,
1144
- AccountCommand :: FillOrder (
1145
- order_id,
1148
+ let version = self
1149
+ . chain_config
1150
+ . chainstate_upgrades ( )
1151
+ . version_at_height ( self . account_info . best_block_height ( ) )
1152
+ . 1
1153
+ . orders_version ( ) ;
1154
+
1155
+ let request = match version {
1156
+ common:: chain:: OrdersVersion :: V0 => {
1157
+ let filled_amount = orders_accounting:: calculate_filled_amount (
1158
+ order_info. ask_balance ,
1159
+ order_info. give_balance ,
1146
1160
fill_amount_in_ask_currency,
1147
- output_destination. clone ( ) ,
1148
- ) ,
1149
- ) ,
1150
- output_destination,
1151
- ) ] ) ;
1161
+ )
1162
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1163
+ let output_value = match order_info. initially_given {
1164
+ RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1165
+ RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1166
+ } ;
1167
+ let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1168
+
1169
+ let nonce = order_info
1170
+ . nonce
1171
+ . map_or ( Some ( AccountNonce :: new ( 0 ) ) , |n| n. increment ( ) )
1172
+ . ok_or ( WalletError :: OrderNonceOverflow ( order_id) ) ?;
1173
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1174
+ TxInput :: AccountCommand (
1175
+ nonce,
1176
+ AccountCommand :: FillOrder (
1177
+ order_id,
1178
+ fill_amount_in_ask_currency,
1179
+ output_destination. clone ( ) ,
1180
+ ) ,
1181
+ ) ,
1182
+ output_destination,
1183
+ ) ] )
1184
+ }
1185
+ common:: chain:: OrdersVersion :: V1 => {
1186
+ let filled_amount = orders_accounting:: calculate_filled_amount (
1187
+ order_info. initially_asked . amount ( ) ,
1188
+ order_info. initially_given . amount ( ) ,
1189
+ fill_amount_in_ask_currency,
1190
+ )
1191
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
1192
+ let output_value = match order_info. initially_given {
1193
+ RpcOutputValue :: Coin { .. } => OutputValue :: Coin ( filled_amount) ,
1194
+ RpcOutputValue :: Token { id, .. } => OutputValue :: TokenV1 ( id, filled_amount) ,
1195
+ } ;
1196
+ let outputs = vec ! [ TxOutput :: Transfer ( output_value, output_destination. clone( ) ) ] ;
1197
+
1198
+ SendRequest :: new ( ) . with_outputs ( outputs) . with_inputs_and_destinations ( [ (
1199
+ TxInput :: OrderAccountCommand ( OrderAccountCommand :: FillOrder (
1200
+ order_id,
1201
+ fill_amount_in_ask_currency,
1202
+ output_destination. clone ( ) ,
1203
+ ) ) ,
1204
+ output_destination,
1205
+ ) ] )
1206
+ }
1207
+ } ;
1152
1208
1153
1209
self . select_inputs_for_send_request (
1154
1210
request,
@@ -1498,10 +1554,20 @@ impl Account {
1498
1554
. ok_or ( WalletError :: DelegationNotFound ( * delegation_id) ) ,
1499
1555
}
1500
1556
}
1501
- TxInput :: OrderAccountCommand ( ..) => {
1502
- // TODO: support OrdersVersion::V1
1503
- unimplemented ! ( )
1504
- }
1557
+ TxInput :: OrderAccountCommand ( cmd) => match cmd {
1558
+ OrderAccountCommand :: FillOrder ( _, _, destination) => {
1559
+ Ok ( ( None , Some ( destination. clone ( ) ) ) )
1560
+ }
1561
+ OrderAccountCommand :: ConcludeOrder {
1562
+ order_id,
1563
+ filled_amount : _,
1564
+ remaining_give_amount : _,
1565
+ } => self
1566
+ . output_cache
1567
+ . order_data ( order_id)
1568
+ . map ( |data| ( None , Some ( data. conclude_key . clone ( ) ) ) )
1569
+ . ok_or ( WalletError :: UnknownOrderId ( * order_id) ) ,
1570
+ } ,
1505
1571
TxInput :: AccountCommand ( _, cmd) => {
1506
1572
match cmd {
1507
1573
// find authority of the token
@@ -2008,10 +2074,16 @@ impl Account {
2008
2074
self . find_delegation ( delegation_id) . is_ok ( )
2009
2075
}
2010
2076
} ,
2011
- TxInput :: OrderAccountCommand ( ..) => {
2012
- // TODO: support OrdersVersion::V1
2013
- unimplemented ! ( )
2014
- }
2077
+ TxInput :: OrderAccountCommand ( cmd) => match cmd {
2078
+ OrderAccountCommand :: FillOrder ( order_id, _, dest) => {
2079
+ self . find_order ( order_id) . is_ok ( ) || self . is_destination_mine_or_watched ( dest)
2080
+ }
2081
+ OrderAccountCommand :: ConcludeOrder {
2082
+ order_id,
2083
+ filled_amount : _,
2084
+ remaining_give_amount : _,
2085
+ } => self . find_order ( order_id) . is_ok ( ) ,
2086
+ } ,
2015
2087
TxInput :: AccountCommand ( _, op) => match op {
2016
2088
AccountCommand :: MintTokens ( token_id, _)
2017
2089
| AccountCommand :: UnmintTokens ( token_id)
@@ -2424,9 +2496,6 @@ fn group_preselected_inputs(
2424
2496
update_preselected_inputs ( Currency :: Coin , * amount, * fee, Amount :: ZERO ) ?;
2425
2497
}
2426
2498
} ,
2427
- TxInput :: OrderAccountCommand ( ..) => {
2428
- // TODO: support OrdersVersion::V1
2429
- }
2430
2499
TxInput :: AccountCommand ( _, op) => match op {
2431
2500
AccountCommand :: MintTokens ( token_id, amount) => {
2432
2501
update_preselected_inputs (
@@ -2476,59 +2545,43 @@ fn group_preselected_inputs(
2476
2545
) ?;
2477
2546
}
2478
2547
AccountCommand :: ConcludeOrder ( order_id) => {
2479
- let order_info = order_info
2480
- . as_ref ( )
2481
- . and_then ( |info| info. get ( order_id) )
2482
- . ok_or ( WalletError :: OrderInfoMissing ( * order_id) ) ?;
2483
-
2484
- let given_currency =
2485
- Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2486
- update_preselected_inputs (
2487
- given_currency,
2488
- order_info. give_balance ,
2489
- Amount :: ZERO ,
2490
- Amount :: ZERO ,
2548
+ handle_conclude_order (
2549
+ * order_id,
2550
+ order_info. as_ref ( ) ,
2551
+ * fee,
2552
+ & mut update_preselected_inputs,
2491
2553
) ?;
2492
-
2493
- let asked_currency =
2494
- Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2495
- let filled_amount = ( order_info. initially_asked . amount ( )
2496
- - order_info. ask_balance )
2497
- . ok_or ( WalletError :: OutputAmountOverflow ) ?;
2498
- update_preselected_inputs (
2499
- asked_currency,
2500
- filled_amount,
2501
- Amount :: ZERO ,
2502
- Amount :: ZERO ,
2503
- ) ?;
2504
-
2505
- // add fee
2506
- update_preselected_inputs ( Currency :: Coin , Amount :: ZERO , * fee, Amount :: ZERO ) ?;
2507
2554
}
2508
2555
AccountCommand :: FillOrder ( order_id, fill_amount_in_ask_currency, _) => {
2509
- let order_info = order_info
2510
- . as_ref ( )
2511
- . and_then ( |info| info. get ( order_id) )
2512
- . ok_or ( WalletError :: OrderInfoMissing ( * order_id) ) ?;
2513
-
2514
- let filled_amount = orders_accounting:: calculate_filled_amount (
2515
- order_info. ask_balance ,
2516
- order_info. give_balance ,
2517
- * fill_amount_in_ask_currency,
2518
- )
2519
- . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( * order_id) ) ?;
2520
-
2521
- let given_currency =
2522
- Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2523
- update_preselected_inputs ( given_currency, filled_amount, * fee, Amount :: ZERO ) ?;
2524
-
2525
- let asked_currency =
2526
- Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2527
- update_preselected_inputs (
2528
- asked_currency,
2529
- Amount :: ZERO ,
2530
- Amount :: ZERO ,
2556
+ handle_fill_order_op (
2557
+ * order_id,
2531
2558
* fill_amount_in_ask_currency,
2559
+ order_info. as_ref ( ) ,
2560
+ * fee,
2561
+ & mut update_preselected_inputs,
2562
+ ) ?;
2563
+ }
2564
+ } ,
2565
+ TxInput :: OrderAccountCommand ( cmd) => match cmd {
2566
+ OrderAccountCommand :: FillOrder ( id, amount, _) => {
2567
+ handle_fill_order_op (
2568
+ * id,
2569
+ * amount,
2570
+ order_info. as_ref ( ) ,
2571
+ * fee,
2572
+ & mut update_preselected_inputs,
2573
+ ) ?;
2574
+ }
2575
+ OrderAccountCommand :: ConcludeOrder {
2576
+ order_id,
2577
+ filled_amount : _,
2578
+ remaining_give_amount : _,
2579
+ } => {
2580
+ handle_conclude_order (
2581
+ * order_id,
2582
+ order_info. as_ref ( ) ,
2583
+ * fee,
2584
+ & mut update_preselected_inputs,
2532
2585
) ?;
2533
2586
}
2534
2587
} ,
@@ -2537,6 +2590,67 @@ fn group_preselected_inputs(
2537
2590
Ok ( preselected_inputs)
2538
2591
}
2539
2592
2593
+ fn handle_fill_order_op (
2594
+ order_id : OrderId ,
2595
+ fill_amount_in_ask_currency : Amount ,
2596
+ order_info : Option < & BTreeMap < OrderId , & RpcOrderInfo > > ,
2597
+ fee : Amount ,
2598
+ update_preselected_inputs : & mut impl FnMut ( Currency , Amount , Amount , Amount ) -> WalletResult < ( ) > ,
2599
+ ) -> WalletResult < ( ) > {
2600
+ let order_info = order_info
2601
+ . as_ref ( )
2602
+ . and_then ( |info| info. get ( & order_id) )
2603
+ . ok_or ( WalletError :: OrderInfoMissing ( order_id) ) ?;
2604
+
2605
+ let filled_amount = orders_accounting:: calculate_filled_amount (
2606
+ order_info. ask_balance ,
2607
+ order_info. give_balance ,
2608
+ fill_amount_in_ask_currency,
2609
+ )
2610
+ . ok_or ( WalletError :: CalculateOrderFilledAmountFailed ( order_id) ) ?;
2611
+
2612
+ let given_currency = Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2613
+ update_preselected_inputs ( given_currency, filled_amount, fee, Amount :: ZERO ) ?;
2614
+
2615
+ let asked_currency = Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2616
+ update_preselected_inputs (
2617
+ asked_currency,
2618
+ Amount :: ZERO ,
2619
+ Amount :: ZERO ,
2620
+ fill_amount_in_ask_currency,
2621
+ ) ?;
2622
+ Ok ( ( ) )
2623
+ }
2624
+
2625
+ fn handle_conclude_order (
2626
+ order_id : OrderId ,
2627
+ order_info : Option < & BTreeMap < OrderId , & RpcOrderInfo > > ,
2628
+ fee : Amount ,
2629
+ update_preselected_inputs : & mut impl FnMut ( Currency , Amount , Amount , Amount ) -> WalletResult < ( ) > ,
2630
+ ) -> WalletResult < ( ) > {
2631
+ let order_info = order_info
2632
+ . as_ref ( )
2633
+ . and_then ( |info| info. get ( & order_id) )
2634
+ . ok_or ( WalletError :: OrderInfoMissing ( order_id) ) ?;
2635
+
2636
+ let given_currency = Currency :: from_rpc_output_value ( & order_info. initially_given ) ;
2637
+ update_preselected_inputs (
2638
+ given_currency,
2639
+ order_info. give_balance ,
2640
+ Amount :: ZERO ,
2641
+ Amount :: ZERO ,
2642
+ ) ?;
2643
+
2644
+ let asked_currency = Currency :: from_rpc_output_value ( & order_info. initially_asked ) ;
2645
+ let filled_amount = ( order_info. initially_asked . amount ( ) - order_info. ask_balance )
2646
+ . ok_or ( WalletError :: OutputAmountOverflow ) ?;
2647
+ update_preselected_inputs ( asked_currency, filled_amount, Amount :: ZERO , Amount :: ZERO ) ?;
2648
+
2649
+ // add fee
2650
+ update_preselected_inputs ( Currency :: Coin , Amount :: ZERO , fee, Amount :: ZERO ) ?;
2651
+ Ok ( ( ) )
2652
+ }
2653
+
2540
2654
/// Calculate the amount of fee that needs to be paid to add a change output
2541
2655
/// Returns the Amounts for Coin output and Token output
2542
2656
fn coin_and_token_output_change_fees (
0 commit comments