Skip to content

Commit 8d5b389

Browse files
authored
Merge pull request #791 from openmina/fix/transaction_pool/non_deterministic_time
Fix Transaction Pool: using non_deterministic time which also isn't compatible with wasm
2 parents a53307c + 3969264 commit 8d5b389

File tree

4 files changed

+30
-55
lines changed

4 files changed

+30
-55
lines changed

ledger/src/transaction_pool.rs

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,54 +1599,13 @@ pub enum ApplyDecision {
15991599
Reject,
16001600
}
16011601

1602-
#[derive(Clone, Debug, Serialize, Deserialize)]
1603-
struct Time {
1604-
nanoseconds_since_unix_epoch: u64,
1605-
}
1606-
1607-
impl Time {
1608-
#[cfg(target_family = "wasm")]
1609-
fn now() -> Self {
1610-
// TODO:
1611-
// https://github.com/janestreet/time_now/blob/d7e3801d2f120b6723c28429de0dd63b669d47b8/src/time_now_stubs.c#L16
1612-
todo!()
1613-
}
1614-
1615-
#[cfg(not(target_family = "wasm"))]
1616-
fn now() -> Self {
1617-
const NANOS_PER_SECOND: u64 = 1000000000;
1618-
1619-
let mut tp = libc::timeval {
1620-
tv_sec: 0,
1621-
tv_usec: 0,
1622-
};
1623-
1624-
let result = unsafe {
1625-
// Use same syscall than OCaml:
1626-
// https://github.com/janestreet/time_now/blob/d7e3801d2f120b6723c28429de0dd63b669d47b8/src/time_now_stubs.c#L30
1627-
libc::gettimeofday(&mut tp, std::ptr::null_mut())
1628-
};
1629-
if result == -1 {
1630-
return Self {
1631-
nanoseconds_since_unix_epoch: 0,
1632-
};
1633-
}
1634-
1635-
Self {
1636-
nanoseconds_since_unix_epoch: NANOS_PER_SECOND
1637-
.wrapping_mul(tp.tv_sec as u64)
1638-
.wrapping_add((tp.tv_usec as u64).wrapping_mul(1000)),
1639-
}
1640-
}
1641-
}
1642-
16431602
const MAX_PER_15_SECONDS: usize = 10;
16441603

16451604
#[derive(Clone, Debug, Serialize, Deserialize)]
16461605
pub struct TransactionPool {
16471606
pub pool: IndexedPool,
1648-
locally_generated_uncommitted: HashMap<ValidCommandWithHash, (Time, Batch)>,
1649-
locally_generated_committed: HashMap<ValidCommandWithHash, (Time, Batch)>,
1607+
locally_generated_uncommitted: HashMap<ValidCommandWithHash, (redux::Timestamp, Batch)>,
1608+
locally_generated_committed: HashMap<ValidCommandWithHash, (redux::Timestamp, Batch)>,
16501609
current_batch: usize,
16511610
remaining_in_batch: usize,
16521611
pub config: Config,
@@ -1964,6 +1923,7 @@ impl TransactionPool {
19641923

19651924
fn apply(
19661925
&mut self,
1926+
time: redux::Timestamp,
19671927
global_slot_since_genesis: Slot,
19681928
current_global_slot: Slot,
19691929
diff: &diff::DiffVerified,
@@ -2079,7 +2039,7 @@ impl TransactionPool {
20792039
continue;
20802040
};
20812041
if !all_dropped_cmd_hashes.contains(&cmd.hash) {
2082-
self.register_locally_generated(cmd);
2042+
self.register_locally_generated(time, cmd);
20832043
}
20842044
}
20852045
}
@@ -2117,6 +2077,7 @@ impl TransactionPool {
21172077

21182078
pub fn unsafe_apply(
21192079
&mut self,
2080+
time: redux::Timestamp,
21202081
global_slot_since_genesis: Slot,
21212082
current_global_slot: Slot,
21222083
diff: &diff::DiffVerified,
@@ -2131,6 +2092,7 @@ impl TransactionPool {
21312092
String,
21322093
> {
21332094
let (decision, accepted, rejected) = self.apply(
2095+
time,
21342096
global_slot_since_genesis,
21352097
current_global_slot,
21362098
diff,
@@ -2140,11 +2102,11 @@ impl TransactionPool {
21402102
Ok((decision, accepted, rejected))
21412103
}
21422104

2143-
fn register_locally_generated(&mut self, cmd: &ValidCommandWithHash) {
2105+
fn register_locally_generated(&mut self, time: redux::Timestamp, cmd: &ValidCommandWithHash) {
21442106
match self.locally_generated_uncommitted.entry(cmd.clone()) {
21452107
Entry::Occupied(mut entry) => {
2146-
let (time, _batch_num) = entry.get_mut();
2147-
*time = Time::now();
2108+
let (entry_time, _batch_num) = entry.get_mut();
2109+
*entry_time = redux::Timestamp::global_now();
21482110
}
21492111
Entry::Vacant(entry) => {
21502112
let batch_num = if self.remaining_in_batch > 0 {
@@ -2155,7 +2117,7 @@ impl TransactionPool {
21552117
self.current_batch += 1;
21562118
self.current_batch
21572119
};
2158-
entry.insert((Time::now(), Batch::Of(batch_num)));
2120+
entry.insert((time, Batch::Of(batch_num)));
21592121
}
21602122
}
21612123
}
@@ -2259,7 +2221,7 @@ impl TransactionPool {
22592221

22602222
fn get_rebroadcastable<F>(&mut self, has_timed_out: F) -> Vec<Vec<UserCommand>>
22612223
where
2262-
F: Fn(&Time) -> bool,
2224+
F: Fn(&redux::Timestamp) -> bool,
22632225
{
22642226
let log = |has_timed_out: bool, s: &str, cmd: &ValidCommandWithHash| -> bool {
22652227
if has_timed_out {

node/src/reducer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn reducer(
7373
Action::TransactionPool(a) => {
7474
crate::transaction_pool::TransactionPoolState::reducer(
7575
Substate::new(state, dispatcher),
76-
a,
76+
meta.with_action(a),
7777
);
7878
}
7979
Action::TransactionPoolEffect(_) => {}

node/src/transaction_pool/mod.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::{
2020
collections::{BTreeMap, BTreeSet, HashMap},
2121
sync::Arc,
2222
};
23+
use transaction_pool_actions::TransactionPoolActionWithMetaRef;
2324

2425
pub mod transaction_pool_actions;
2526

@@ -106,13 +107,13 @@ impl TransactionPoolState {
106107
}
107108
}
108109

109-
pub fn reducer(mut state: crate::Substate<Self>, action: &TransactionPoolAction) {
110+
pub fn reducer(mut state: crate::Substate<Self>, action: TransactionPoolActionWithMetaRef<'_>) {
110111
// Uncoment following line to save actions to `/tmp/pool.bin`
111112
// Self::save_actions(&mut state);
112113

113114
let substate = state.get_substate_mut().unwrap();
114115
if let Some(file) = substate.file.as_mut() {
115-
postcard::to_io(action, file).unwrap();
116+
postcard::to_io(&action, file).unwrap();
116117
};
117118

118119
Self::handle_action(state, action)
@@ -125,7 +126,11 @@ impl TransactionPoolState {
125126
))
126127
}
127128

128-
fn handle_action(mut state: crate::Substate<Self>, action: &TransactionPoolAction) {
129+
fn handle_action(
130+
mut state: crate::Substate<Self>,
131+
action: TransactionPoolActionWithMetaRef<'_>,
132+
) {
133+
let (action, meta) = action.split();
129134
let Some((global_slot, global_slot_from_genesis)) =
130135
// TODO: remove usage of `unsafe_get_state`
131136
Self::global_slots(state.unsafe_get_state())
@@ -293,6 +298,7 @@ impl TransactionPoolState {
293298

294299
// Note(adonagy): Action for rebroadcast, in his action we can use forget_check
295300
match substate.pool.unsafe_apply(
301+
meta.time(),
296302
global_slot_from_genesis,
297303
global_slot,
298304
&diff,
@@ -444,6 +450,7 @@ mod tests {
444450
use super::*;
445451
use crate::State;
446452
use redux::Dispatcher;
453+
use transaction_pool_actions::TransactionPoolActionWithMeta;
447454

448455
#[allow(unused)]
449456
#[test]
@@ -454,13 +461,16 @@ mod tests {
454461
let (mut state, rest) = postcard::take_from_bytes::<State>(slice).unwrap();
455462
let mut slice = rest;
456463

457-
while let Ok((action, rest)) = postcard::take_from_bytes::<TransactionPoolAction>(slice) {
464+
while let Ok((action, rest)) =
465+
postcard::take_from_bytes::<TransactionPoolActionWithMeta>(slice)
466+
{
458467
slice = rest;
459468

460469
let mut dispatcher = Dispatcher::new();
461470
let state = crate::Substate::<TransactionPoolState>::new(&mut state, &mut dispatcher);
471+
let (action, meta) = action.split();
462472

463-
TransactionPoolState::handle_action(state, &action);
473+
TransactionPoolState::handle_action(state, meta.with_action(&action));
464474
}
465475
}
466476
}

node/src/transaction_pool/transaction_pool_actions.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ use crate::ledger::LedgerService;
1919

2020
use super::PendingId;
2121

22+
pub type TransactionPoolActionWithMeta = redux::ActionWithMeta<TransactionPoolAction>;
23+
pub type TransactionPoolActionWithMetaRef<'a> = redux::ActionWithMeta<&'a TransactionPoolAction>;
24+
2225
#[derive(Serialize, Deserialize, Debug, Clone, ActionEvent)]
2326
#[action_event(level = info)]
2427
pub enum TransactionPoolAction {

0 commit comments

Comments
 (0)