@@ -7,13 +7,13 @@ use sp_core::crypto::KeyTypeId;
7
7
pub use crate :: weights:: WeightInfo ;
8
8
pub use pallet:: * ;
9
9
10
+ pub use scale_info:: prelude:: vec:: Vec ;
10
11
pub use sp_core:: offchain:: Timestamp ;
11
12
use sp_runtime:: offchain:: { http, Duration } ;
12
13
pub use sp_std:: sync:: Arc ;
13
- pub use scale_info:: prelude:: vec:: Vec ;
14
14
15
15
pub mod configuration;
16
- use configuration:: OrderBookServiceURL ;
16
+ use configuration:: OrderBookServiceURLs ;
17
17
18
18
#[ cfg( test) ]
19
19
mod mock;
@@ -29,13 +29,13 @@ pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"ocw!");
29
29
30
30
pub mod crypto {
31
31
use super :: KEY_TYPE ;
32
+ use scale_info:: prelude:: string:: String ;
32
33
use sp_core:: sr25519:: Signature as Sr25519Signature ;
33
34
use sp_runtime:: {
34
35
app_crypto:: { app_crypto, sr25519} ,
35
36
traits:: Verify ,
36
37
MultiSignature , MultiSigner ,
37
38
} ;
38
- use scale_info:: prelude:: string:: String ;
39
39
40
40
app_crypto ! ( sr25519, KEY_TYPE ) ;
41
41
@@ -61,8 +61,7 @@ pub mod crypto {
61
61
pub mod pallet {
62
62
use super :: * ;
63
63
use frame_support:: {
64
- pallet_prelude:: * , require_transactional, sp_runtime:: traits:: Hash ,
65
- transactional,
64
+ pallet_prelude:: * , require_transactional, sp_runtime:: traits:: Hash , transactional,
66
65
} ;
67
66
use frame_system:: {
68
67
offchain:: {
@@ -72,9 +71,9 @@ pub mod pallet {
72
71
pallet_prelude:: * ,
73
72
} ;
74
73
use gsy_primitives:: v0:: {
75
- Bid , InputOrder , Offer , Order , OrderReference , OrderSchema ,
76
- OrderStatus ,
74
+ Bid , InputOrder , Offer , Order , OrderReference , OrderSchema , OrderStatus ,
77
75
} ;
76
+ use gsy_primitives:: Trade ;
78
77
use scale_info:: prelude:: vec;
79
78
use scale_info:: TypeInfo ;
80
79
use sp_runtime:: offchain:: http:: Request ;
@@ -101,24 +100,33 @@ pub mod pallet {
101
100
type UnsignedPriority : Get < TransactionPriority > ;
102
101
103
102
type WeightInfo : WeightInfo ;
104
-
105
103
}
106
104
107
105
#[ pallet:: pallet]
108
106
// #[pallet::generate_store(pub (super) trait Store)]
109
107
pub struct Pallet < T > ( _ ) ;
110
108
111
109
#[ pallet:: storage]
112
- #[ pallet:: getter( fn orders_book ) ]
110
+ #[ pallet:: getter( fn orderbook ) ]
113
111
/// Temporary orders book for Orderbook workers.
114
- pub type Orderbook < T : Config > = StorageMap <
112
+ pub type OrdersForWorker < T : Config > = StorageMap <
115
113
_ ,
116
114
Twox64Concat ,
117
115
OrderReference < T :: AccountId , T :: Hash > ,
118
116
Order < T :: AccountId > ,
119
117
OptionQuery ,
120
118
> ;
121
119
120
+ #[ pallet:: storage]
121
+ #[ pallet:: getter( fn trades_for_worker) ]
122
+ /// Temporary trades for Orderbook workers.
123
+ pub type TradesForWorker < T : Config > = StorageMap <
124
+ _ ,
125
+ Twox64Concat ,
126
+ T :: Hash ,
127
+ Trade < T :: AccountId , T :: Hash > ,
128
+ > ;
129
+
122
130
#[ pallet:: storage]
123
131
#[ pallet:: getter( fn user_nonce) ]
124
132
pub type UserNonce < T : Config > = StorageMap < _ , Twox64Concat , T :: AccountId , u32 > ;
@@ -133,6 +141,9 @@ pub mod pallet {
133
141
OrderRemoved ( T :: AccountId , T :: Hash ) ,
134
142
/// New Order added to the orders book \[sender, hash\].
135
143
NewOrderInserted ( Order < T :: AccountId > , T :: Hash ) ,
144
+ NewTradeInserted ( Trade < T :: AccountId , T :: Hash > , T :: Hash ) ,
145
+ /// Order has been deleted from the book.
146
+ TradeRemoved ( T :: Hash ) ,
136
147
}
137
148
138
149
#[ pallet:: error]
@@ -143,6 +154,7 @@ pub mod pallet {
143
154
NoLocalAcctForSigning ,
144
155
NonceCheckOverflow ,
145
156
OrderIsNotRegistered ,
157
+ TradeIsNotRegistered ,
146
158
NotARootUser ,
147
159
InsufficientCollateral ,
148
160
InvalidNonce ,
@@ -205,7 +217,10 @@ pub mod pallet {
205
217
) ;
206
218
let hashed_orders = Self :: create_hash_vec_from_order_list ( orders. clone ( ) ) ;
207
219
let _ = <orderbook_registry:: Pallet < T > >:: insert_orders_by_proxy (
208
- origin, delegator. clone ( ) , hashed_orders) ;
220
+ origin,
221
+ delegator. clone ( ) ,
222
+ hashed_orders,
223
+ ) ;
209
224
for order in orders {
210
225
Self :: add_order ( delegator. clone ( ) , Self :: input_order_to_order ( order) ) ?;
211
226
}
@@ -220,10 +235,7 @@ pub mod pallet {
220
235
#[ transactional]
221
236
#[ pallet:: weight( < T as Config >:: WeightInfo :: remove_orders( ) ) ]
222
237
#[ pallet:: call_index( 2 ) ]
223
- pub fn remove_orders (
224
- origin : OriginFor < T > ,
225
- orders_hash : Vec < T :: Hash > ,
226
- ) -> DispatchResult {
238
+ pub fn remove_orders ( origin : OriginFor < T > , orders_hash : Vec < T :: Hash > ) -> DispatchResult {
227
239
let sender = ensure_signed ( origin. clone ( ) ) ?;
228
240
log:: info!( "remove orders: {:?} for the user: {:?}" , orders_hash, sender) ;
229
241
let _ = <orderbook_registry:: Pallet < T > >:: delete_orders ( origin, orders_hash) ;
@@ -252,10 +264,7 @@ pub mod pallet {
252
264
) ;
253
265
let mut hash_vector = Vec :: < T :: Hash > :: new ( ) ;
254
266
hash_vector. push ( payload. hash ) ;
255
- <orderbook_registry:: Pallet < T > >:: delete_orders (
256
- origin. clone ( ) ,
257
- hash_vector,
258
- ) ?;
267
+ <orderbook_registry:: Pallet < T > >:: delete_orders ( origin. clone ( ) , hash_vector) ?;
259
268
Self :: delete_order ( payload) ?;
260
269
}
261
270
Ok ( ( ) )
@@ -309,7 +318,10 @@ pub mod pallet {
309
318
) ;
310
319
311
320
let _ = <orderbook_registry:: Pallet < T > >:: delete_orders_by_proxy (
312
- origin, delegator. clone ( ) , orders_hash. clone ( ) ) ;
321
+ origin,
322
+ delegator. clone ( ) ,
323
+ orders_hash. clone ( ) ,
324
+ ) ;
313
325
Ok ( ( ) )
314
326
}
315
327
}
@@ -402,7 +414,10 @@ pub mod pallet {
402
414
403
415
let mut orders = Vec :: < Order < T :: AccountId > > :: new ( ) ;
404
416
405
- for ( order_ref, order) in <Orderbook < T > >:: iter ( ) {
417
+ let mut trades = Vec :: < Trade < T :: AccountId , T :: Hash > > :: new ( ) ;
418
+ let mut trade_hashes = Vec :: < T :: Hash > :: new ( ) ;
419
+
420
+ for ( order_ref, order) in <OrdersForWorker < T > >:: iter ( ) {
406
421
match & order {
407
422
_order_in_book => {
408
423
log:: info!(
@@ -438,16 +453,84 @@ pub mod pallet {
438
453
. expect ( "Error while removing processed orders" ) ;
439
454
}
440
455
}
456
+
457
+ // TODO: Trades transmission process starts here
458
+
459
+ for ( trade_hash, trade) in <TradesForWorker < T > >:: iter ( ) {
460
+ match & trade {
461
+ _trade_in_book => {
462
+ log:: info!(
463
+ "Offchain process: reference: {:?}, order: {:?}" ,
464
+ & trade_hash,
465
+ & trade
466
+ ) ;
467
+ trades. push ( trade) ;
468
+ trade_hashes. push ( trade_hash) ;
469
+ } ,
470
+ }
471
+ }
472
+
473
+ if !trades. is_empty ( ) {
474
+ // let trade_schema: Vec<Trade<T::AccountId, T::Hash>> = trades
475
+ // .clone()
476
+ // .into_iter()
477
+ // .map(|trade| Trade {
478
+ // seller: trade.seller,
479
+ // buyer: trade.buyer,
480
+ // market_id: trade.market_id,
481
+ // trade_uuid: trade.trade_uuid,
482
+ // creation_time: trade.creation_time,
483
+ // time_slot: trade.time_slot,
484
+ // offer: trade.offer,
485
+ // offer_hash: trade.offer_hash,
486
+ // bid: trade.bid,
487
+ // bid_hash: trade.bid_hash,
488
+ // residual_offer
489
+ //
490
+ // })
491
+ // .collect();
492
+ let bytes = trades. encode ( ) ;
493
+ let bytes_to_json: Vec < u8 > = serde_json:: to_vec ( & bytes) . unwrap ( ) ;
494
+ let post_trades_status_code =
495
+ Self :: send_trade_to_orderbook_service ( & bytes_to_json) . unwrap ( ) ;
496
+
497
+ if post_trades_status_code != 200 {
498
+ log:: warn!(
499
+ "Offchain worker failed to send trades to the orderbook service, HTTP \
500
+ response code {}", post_trades_status_code)
501
+ }
502
+ else {
503
+ for trade_hash in trade_hashes {
504
+ Self :: delete_trade ( trade_hash) . unwrap ( ) ;
505
+ }
506
+ }
507
+ }
508
+ }
509
+
510
+ pub fn send_trade_to_orderbook_service ( request_body : & [ u8 ] ) -> Result < u16 , http:: Error > {
511
+ // deadline sets the offchain worker execution time minimal as possible. So we hard
512
+ // code the duration to 2s to complete the external call to the database to post the
513
+ // orders.
514
+ let orderbook_service_urls = OrderBookServiceURLs :: default ( ) ;
515
+ let deadline = sp_io:: offchain:: timestamp ( ) . add ( Duration :: from_millis ( 2_000 ) ) ;
516
+ let request = Request :: post ( & orderbook_service_urls. trades_url , vec ! [ & request_body] ) ;
517
+ let pending = request
518
+ . deadline ( deadline)
519
+ . add_header ( "Content-Type" , "application/json" )
520
+ . send ( )
521
+ . map_err ( |_| http:: Error :: DeadlineReached ) ?;
522
+ let response =
523
+ pending. try_wait ( deadline) . map_err ( |_| http:: Error :: DeadlineReached ) ??;
524
+ Ok ( response. code )
441
525
}
442
526
443
527
pub fn send_order_to_orderbook_service ( request_body : & [ u8 ] ) -> Result < u16 , http:: Error > {
444
528
// deadline sets the offchain worker execution time minimal as possible. So we hard
445
529
// code the duration to 2s to complete the external call to the database to post the
446
530
// orders.
447
- let orderbook_service_url = OrderBookServiceURL :: default ( ) ;
448
- let full_url = orderbook_service_url. with_endpoint ( "orders" ) ;
531
+ let orderbook_service_url = OrderBookServiceURLs :: default ( ) ;
449
532
let deadline = sp_io:: offchain:: timestamp ( ) . add ( Duration :: from_millis ( 2_000 ) ) ;
450
- let request = Request :: post ( & full_url , vec ! [ & request_body] ) ;
533
+ let request = Request :: post ( & orderbook_service_url . orders_url , vec ! [ & request_body] ) ;
451
534
let pending = request
452
535
. deadline ( deadline)
453
536
. add_header ( "Content-Type" , "application/json" )
@@ -536,10 +619,7 @@ pub mod pallet {
536
619
/// `sender`: The sender of the order.
537
620
/// `order`: The order to be inserted.
538
621
#[ require_transactional]
539
- pub fn add_order (
540
- sender : T :: AccountId ,
541
- order : Order < T :: AccountId > ,
542
- ) -> DispatchResult {
622
+ pub fn add_order ( sender : T :: AccountId , order : Order < T :: AccountId > ) -> DispatchResult {
543
623
ensure ! (
544
624
<gsy_collateral:: Pallet <T >>:: verify_collateral_amount(
545
625
Self :: get_order_amount( order. clone( ) ) ,
@@ -550,11 +630,25 @@ pub mod pallet {
550
630
let order_hash = T :: Hashing :: hash_of ( & order) ;
551
631
let order_reference =
552
632
OrderReference { user_id : sender. clone ( ) , hash : order_hash. clone ( ) } ;
553
- <Orderbook < T > >:: insert ( order_reference, order. clone ( ) ) ;
633
+ <OrdersForWorker < T > >:: insert ( order_reference, order. clone ( ) ) ;
554
634
Self :: deposit_event ( Event :: NewOrderInserted ( order, order_hash) ) ;
555
635
Ok ( ( ) )
556
636
}
557
637
638
+ /// Insert a new trade object into the Trades storage for offchain worker to relay them to
639
+ /// orderbook service.
640
+ ///
641
+ /// Parameters
642
+ /// `sender`: The sender of the trade.
643
+ /// `trade`: The order to be inserted.
644
+ #[ require_transactional]
645
+ pub fn add_trade ( _sender : T :: AccountId , trade : Trade < T :: AccountId , T :: Hash > ) -> DispatchResult {
646
+ let trade_hash = T :: Hashing :: hash_of ( & trade) ;
647
+ <TradesForWorker < T > >:: insert ( trade_hash, trade. clone ( ) ) ;
648
+ Self :: deposit_event ( Event :: NewTradeInserted ( trade, trade_hash) ) ;
649
+ Ok ( ( ) )
650
+ }
651
+
558
652
/// Get nonce for the order.
559
653
///
560
654
/// Parameters
@@ -563,31 +657,51 @@ pub mod pallet {
563
657
/// `u32`: The nonce for the order.
564
658
pub fn get_and_increment_user_nonce ( sender : T :: AccountId ) -> u32 {
565
659
let user_nonce = <UserNonce < T > >:: get ( sender. clone ( ) ) . unwrap_or ( 0u32 ) ;
566
- let nonce = user_nonce. checked_add ( 1u32 )
567
- . ok_or ( <Error < T > >:: NonceCheckOverflow ) . unwrap ( ) ;
660
+ let nonce = user_nonce. checked_add ( 1u32 ) . ok_or ( <Error < T > >:: NonceCheckOverflow ) . unwrap ( ) ;
568
661
<UserNonce < T > >:: insert ( sender. clone ( ) , nonce) ;
569
662
user_nonce
570
663
}
571
664
572
- /// Remove a order from the orders book.
665
+ /// Remove an order from the orders book.
573
666
///
574
667
/// Parameters
575
668
/// `order_reference`: The order reference.
576
669
pub fn delete_order (
577
670
order_reference : OrderReference < T :: AccountId , T :: Hash > ,
578
671
) -> DispatchResult {
579
672
ensure ! ( Self :: is_order_registered( & order_reference) , <Error <T >>:: OrderIsNotRegistered ) ;
580
- <Orderbook < T > >:: remove ( order_reference. clone ( ) ) ;
673
+ <OrdersForWorker < T > >:: remove ( order_reference. clone ( ) ) ;
581
674
Self :: deposit_event ( Event :: OrderRemoved ( order_reference. user_id , order_reference. hash ) ) ;
582
675
Ok ( ( ) )
583
676
}
584
677
678
+ /// Remove a trade from the offchain worker storage.
679
+ ///
680
+ /// Parameters
681
+ /// `trade_hash`: The hash of the trade object.
682
+ pub fn delete_trade (
683
+ trade_hash : T :: Hash ,
684
+ ) -> DispatchResult {
685
+ ensure ! ( Self :: is_trade_registered( & trade_hash) , <Error <T >>:: TradeIsNotRegistered ) ;
686
+ <TradesForWorker < T > >:: remove ( trade_hash) ;
687
+ Self :: deposit_event ( Event :: TradeRemoved ( trade_hash) ) ;
688
+ Ok ( ( ) )
689
+ }
690
+
691
+ /// Helper function to check if a given order has already been registered.
692
+ ///
693
+ /// Parameters
694
+ /// `trade_hash`: The hash of the trade.
695
+ pub fn is_trade_registered ( trade_hash : & T :: Hash ) -> bool {
696
+ <TradesForWorker < T > >:: contains_key ( trade_hash)
697
+ }
698
+
585
699
/// Helper function to check if a given order has already been registered.
586
700
///
587
701
/// Parameters
588
702
/// `order_ref`: The order reference.
589
703
pub fn is_order_registered ( order_ref : & OrderReference < T :: AccountId , T :: Hash > ) -> bool {
590
- <Orderbook < T > >:: contains_key ( order_ref)
704
+ <OrdersForWorker < T > >:: contains_key ( order_ref)
591
705
}
592
706
593
707
/// Helper function to get the user_id of the order
@@ -622,14 +736,15 @@ pub mod pallet {
622
736
}
623
737
}
624
738
625
- pub fn create_hash_vec_from_order_list ( orders : Vec < InputOrder < T :: AccountId > > ) -> Vec < T :: Hash > {
739
+ pub fn create_hash_vec_from_order_list (
740
+ orders : Vec < InputOrder < T :: AccountId > > ,
741
+ ) -> Vec < T :: Hash > {
626
742
return orders
627
743
. clone ( )
628
744
. into_iter ( )
629
745
. map ( |order| Self :: input_order_to_order ( order) )
630
746
. map ( |order| T :: Hashing :: hash_of ( & order) )
631
747
. collect ( ) ;
632
748
}
633
-
634
749
}
635
750
}
0 commit comments