1
1
use call:: { DeferredCallDeserializer , DeferredCallSerializer } ;
2
2
use macros:: DEFERRED_CALL_TOTAL_GAS ;
3
3
use massa_db_exports:: {
4
- DBBatch , ShareableMassaDBController , CRUD_ERROR , DEFERRED_CALLS_SLOT_PREFIX , KEY_SER_ERROR ,
5
- MESSAGE_DESER_ERROR , MESSAGE_SER_ERROR , STATE_CF ,
4
+ DBBatch , ShareableMassaDBController , CRUD_ERROR , DEFERRED_CALLS_SLOT_PREFIX , KEY_DESER_ERROR ,
5
+ KEY_SER_ERROR , MESSAGE_DESER_ERROR , MESSAGE_SER_ERROR , STATE_CF ,
6
6
} ;
7
7
use massa_serialization:: { DeserializeError , Deserializer , Serializer } ;
8
- use registry_changes:: { DeferredRegistryChanges , DeferredRegistryChangesDeserializer } ;
8
+ use registry_changes:: {
9
+ DeferredRegistryChanges , DeferredRegistryChangesDeserializer , DeferredRegistryChangesSerializer ,
10
+ } ;
9
11
10
12
/// This module implements a new version of the Autonomous Smart Contracts. (ASC)
11
13
/// This new version allow asynchronous calls to be registered for a specific slot and ensure his execution.
@@ -21,7 +23,7 @@ use massa_ledger_exports::{SetOrDelete, SetOrKeep};
21
23
use massa_models:: {
22
24
amount:: Amount ,
23
25
config:: THREAD_COUNT ,
24
- deferred_call_id:: { DeferredCallId , DeferredCallIdSerializer } ,
26
+ deferred_call_id:: { DeferredCallId , DeferredCallIdDeserializer , DeferredCallIdSerializer } ,
25
27
slot:: Slot ,
26
28
} ;
27
29
use std:: collections:: BTreeMap ;
@@ -32,7 +34,9 @@ pub struct DeferredCallRegistry {
32
34
call_serializer : DeferredCallSerializer ,
33
35
call_id_serializer : DeferredCallIdSerializer ,
34
36
call_deserializer : DeferredCallDeserializer ,
37
+ call_id_deserializer : DeferredCallIdDeserializer ,
35
38
registry_changes_deserializer : DeferredRegistryChangesDeserializer ,
39
+ registry_changes_serializer : DeferredRegistryChangesSerializer ,
36
40
}
37
41
38
42
impl DeferredCallRegistry {
@@ -51,17 +55,53 @@ impl DeferredCallRegistry {
51
55
call_serializer : DeferredCallSerializer :: new ( ) ,
52
56
call_id_serializer : DeferredCallIdSerializer :: new ( ) ,
53
57
call_deserializer : DeferredCallDeserializer :: new ( THREAD_COUNT ) ,
58
+ call_id_deserializer : DeferredCallIdDeserializer :: new ( ) ,
54
59
// todo args
55
60
registry_changes_deserializer : DeferredRegistryChangesDeserializer :: new (
56
61
THREAD_COUNT ,
57
62
100_000 ,
58
63
100_000 ,
59
64
) ,
65
+ registry_changes_serializer : DeferredRegistryChangesSerializer :: new ( ) ,
60
66
}
61
67
}
62
68
63
69
pub fn get_slot_calls ( & self , slot : Slot ) -> DeferredSlotCalls {
64
- todo ! ( )
70
+ let mut to_return = DeferredSlotCalls :: new ( slot) ;
71
+ let key = deferred_slot_call_prefix_key ! ( slot. to_bytes_key( ) ) ;
72
+
73
+ // cache the call ids to avoid duplicates iteration
74
+ let mut temp = Vec :: new ( ) ;
75
+
76
+ for ( serialized_key, _serialized_value) in self . db . read ( ) . prefix_iterator_cf ( STATE_CF , & key)
77
+ {
78
+ if !serialized_key. starts_with ( & key) {
79
+ break ;
80
+ }
81
+
82
+ let rest_key = & serialized_key[ key. len ( ) ..] ;
83
+
84
+ let ( _rest, call_id) = self
85
+ . call_id_deserializer
86
+ . deserialize :: < DeserializeError > ( & rest_key)
87
+ . expect ( KEY_DESER_ERROR ) ;
88
+
89
+ if temp. contains ( & call_id) {
90
+ continue ;
91
+ }
92
+
93
+ temp. push ( call_id. clone ( ) ) ;
94
+
95
+ if let Some ( call) = self . get_call ( & slot, & call_id) {
96
+ to_return. slot_calls . insert ( call_id, call) ;
97
+ }
98
+ }
99
+
100
+ to_return. slot_base_fee = self . get_slot_base_fee ( & slot) ;
101
+ to_return. slot_gas = self . get_slot_gas ( slot) ;
102
+ to_return. total_gas = self . get_total_gas ( ) ;
103
+
104
+ to_return
65
105
}
66
106
67
107
/// Returns the DeferredCall for a given slot and id
@@ -111,13 +151,17 @@ impl DeferredCallRegistry {
111
151
112
152
/// Returns the base fee for a slot
113
153
pub fn get_slot_base_fee ( & self , slot : & Slot ) -> Amount {
114
- unimplemented ! ( "get_slot_base_fee" ) ;
115
- // self.db.read().get_cf(handle_cf, key)
116
- // // By default, if it is absent, it is 0
117
- // self.db.read().get
118
- // .get(ASYNC_CAL_SLOT_PREFIX, slot, BASE_FEE_TAG)
119
- // .map(|v| Amount::from_bytes(v).unwrap())
120
- // .unwrap_or(Amount::zero())
154
+ let key = deferred_call_slot_base_fee_key ! ( slot. to_bytes_key( ) ) ;
155
+ match self . db . read ( ) . get_cf ( STATE_CF , key) {
156
+ Ok ( Some ( v) ) => {
157
+ self . call_deserializer
158
+ . amount_deserializer
159
+ . deserialize :: < DeserializeError > ( & v)
160
+ . expect ( MESSAGE_DESER_ERROR )
161
+ . 1
162
+ }
163
+ _ => Amount :: zero ( ) ,
164
+ }
121
165
}
122
166
123
167
/// Returns the total amount of gas booked
@@ -322,6 +366,21 @@ impl DeferredCallRegistry {
322
366
DeferredRegistryBaseFeeChange :: Keep => { }
323
367
}
324
368
}
369
+
370
+ match changes. total_gas {
371
+ DeferredRegistryGasChange :: Set ( v) => {
372
+ let key = DEFERRED_CALL_TOTAL_GAS . as_bytes ( ) . to_vec ( ) ;
373
+ let mut value_ser = Vec :: new ( ) ;
374
+ self . registry_changes_serializer
375
+ . total_gas_serializer
376
+ . serialize ( & DeferredRegistryGasChange :: Set ( v) , & mut value_ser)
377
+ . expect ( MESSAGE_SER_ERROR ) ;
378
+ self . db
379
+ . read ( )
380
+ . put_or_update_entry_value ( batch, key, & value_ser) ;
381
+ }
382
+ DeferredRegistryGasChange :: Keep => { }
383
+ }
325
384
}
326
385
}
327
386
@@ -424,10 +483,7 @@ impl DeferredSlotCalls {
424
483
mod tests {
425
484
use super :: * ;
426
485
use crate :: { DeferredCall , DeferredCallRegistry , DeferredRegistryChanges } ;
427
- use massa_db_exports:: {
428
- DBBatch , Key , MassaDBConfig , MassaDBController , ShareableMassaDBController ,
429
- DEFERRED_CALLS_SLOT_PREFIX , STATE_CF ,
430
- } ;
486
+ use massa_db_exports:: { DBBatch , MassaDBConfig , MassaDBController , ShareableMassaDBController } ;
431
487
use massa_db_worker:: MassaDB ;
432
488
use massa_models:: {
433
489
address:: Address ,
@@ -437,7 +493,7 @@ mod tests {
437
493
slot:: Slot ,
438
494
} ;
439
495
use parking_lot:: RwLock ;
440
- use std:: { str:: FromStr , sync:: Arc } ;
496
+ use std:: { result , str:: FromStr , sync:: Arc } ;
441
497
use tempfile:: tempdir;
442
498
443
499
#[ test]
@@ -491,4 +547,69 @@ mod tests {
491
547
assert ! ( result. target_function. eq( & call. target_function) ) ;
492
548
assert_eq ! ( result. sender_address, call. sender_address) ;
493
549
}
550
+
551
+ #[ test]
552
+ fn get_slot_calls ( ) {
553
+ let temp_dir = tempdir ( ) . expect ( "Unable to create a temp folder" ) ;
554
+ let db_config = MassaDBConfig {
555
+ path : temp_dir. path ( ) . to_path_buf ( ) ,
556
+ max_history_length : 100 ,
557
+ max_final_state_elements_size : 100 ,
558
+ max_versioning_elements_size : 100 ,
559
+ thread_count : THREAD_COUNT ,
560
+ max_ledger_backups : 100 ,
561
+ } ;
562
+ let call_id_serializer = DeferredCallIdSerializer :: new ( ) ;
563
+ let db: ShareableMassaDBController = Arc :: new ( RwLock :: new (
564
+ Box :: new ( MassaDB :: new ( db_config) ) as Box < ( dyn MassaDBController + ' static ) > ,
565
+ ) ) ;
566
+
567
+ let registry = DeferredCallRegistry :: new ( db) ;
568
+
569
+ let mut changes = DeferredRegistryChanges :: default ( ) ;
570
+
571
+ let target_slot = Slot {
572
+ thread : 5 ,
573
+ period : 1 ,
574
+ } ;
575
+
576
+ let call = DeferredCall :: new (
577
+ Address :: from_str ( "AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x" ) . unwrap ( ) ,
578
+ target_slot. clone ( ) ,
579
+ Address :: from_str ( "AS127QtY6Hzm6BnJc9wqCBfPNvEH9fKer3LiMNNQmcX3MzLwCL6G6" ) . unwrap ( ) ,
580
+ "receive" . to_string ( ) ,
581
+ vec ! [ 42 , 42 , 42 , 42 ] ,
582
+ Amount :: from_raw ( 100 ) ,
583
+ 3000000 ,
584
+ Amount :: from_raw ( 1 ) ,
585
+ false ,
586
+ ) ;
587
+ let id = DeferredCallId :: new ( 0 , target_slot. clone ( ) , 1 , & [ ] ) . unwrap ( ) ;
588
+
589
+ let id2 = DeferredCallId :: new ( 0 , target_slot. clone ( ) , 1 , & [ 123 ] ) . unwrap ( ) ;
590
+
591
+ let mut buf_id = Vec :: new ( ) ;
592
+ call_id_serializer. serialize ( & id, & mut buf_id) . unwrap ( ) ;
593
+
594
+ changes. set_call ( id. clone ( ) , call. clone ( ) ) ;
595
+ changes. set_call ( id2. clone ( ) , call. clone ( ) ) ;
596
+ changes. set_total_gas ( 100 ) ;
597
+ changes. set_slot_gas ( target_slot. clone ( ) , 100_000 ) ;
598
+
599
+ changes. set_slot_base_fee ( target_slot. clone ( ) , Amount :: from_raw ( 10000000 ) ) ;
600
+
601
+ let mut batch = DBBatch :: new ( ) ;
602
+ registry. apply_changes_to_batch ( changes, & mut batch) ;
603
+
604
+ registry. db . write ( ) . write_batch ( batch, DBBatch :: new ( ) , None ) ;
605
+
606
+ let result = registry. get_slot_calls ( target_slot. clone ( ) ) ;
607
+
608
+ assert ! ( result. slot_calls. len( ) == 2 ) ;
609
+ assert ! ( result. slot_calls. contains_key( & id) ) ;
610
+ assert ! ( result. slot_calls. contains_key( & id2) ) ;
611
+ assert_eq ! ( result. total_gas, 100 ) ;
612
+ assert_eq ! ( result. slot_base_fee, Amount :: from_raw( 10000000 ) ) ;
613
+ assert_eq ! ( result. slot_gas, 100_000 ) ;
614
+ }
494
615
}
0 commit comments