Skip to content

Commit 9cd11a1

Browse files
committed
Update the data fetching endpoints on the ledger canister
1 parent 219aaca commit 9cd11a1

File tree

7 files changed

+84
-39
lines changed

7 files changed

+84
-39
lines changed

cli/src/argparse.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,23 @@ pub fn parse_args() -> clap::ArgMatches {
162162
.num_args(1),
163163
)
164164
.arg(
165-
Arg::new("push-authorize")
166-
.long("push_authorize")
165+
Arg::new("data-fetch")
166+
.long("data-fetch")
167+
.visible_aliases(&["fetch", "pull"])
168+
.action(ArgAction::SetTrue)
169+
.help("Sync data from the ledger"),
170+
)
171+
.arg(
172+
Arg::new("data-push-authorize")
173+
.long("data-push-authorize")
174+
.visible_aliases(&["push-authorize", "push-auth"])
167175
.help("Authorize push to the Decent Cloud Ledger")
168176
.action(ArgAction::SetTrue),
169177
)
170178
.arg(
171-
Arg::new("push")
172-
.long("push")
179+
Arg::new("data-push")
180+
.long("data-push")
181+
.visible_aliases(&["push"])
173182
.help("Push the ledger entries to the Decent Cloud Ledger")
174183
.action(ArgAction::SetTrue)
175184
)
@@ -192,12 +201,6 @@ pub fn parse_args() -> clap::ArgMatches {
192201
.default_value("127.0.0.1")
193202
.help("Which IC network to use"),
194203
)
195-
.arg(
196-
Arg::new("fetch")
197-
.long("fetch")
198-
.action(ArgAction::SetTrue)
199-
.help("Sync from the ledger"),
200-
),
201204
)
202205
.get_matches()
203206
}

cli/src/ledger_canister_client.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ impl LedgerCanister {
6363
"node_provider_register".to_string(),
6464
"node_provider_check_in".to_string(),
6565
"node_provider_update_profile".to_string(),
66+
"data_push".to_string(),
67+
"data_push_auth".to_string(),
6668
]
6769
}
6870

6971
pub fn list_functions_queries(&self) -> Vec<String> {
7072
vec![
7173
"get_np_check_in_nonce".to_string(),
72-
"fetch".to_string(),
74+
"data_fetch".to_string(),
7375
"metadata".to_string(),
7476
"get_logs_debug".to_string(),
7577
"get_logs_info".to_string(),
@@ -117,9 +119,13 @@ impl LedgerCanister {
117119
Decode!(response.as_slice(), Vec<u8>).expect("Failed to decode response")
118120
}
119121

120-
pub async fn fetch(&self, cursor: Option<String>) -> Result<(String, Vec<u8>), String> {
121-
let args = Encode!(&(cursor)).map_err(|e| e.to_string())?;
122-
let response = self.call_query("fetch", &args).await?;
122+
pub async fn data_fetch(
123+
&self,
124+
cursor: Option<String>,
125+
bytes_before: Option<Vec<u8>>,
126+
) -> Result<(String, Vec<u8>), String> {
127+
let args = Encode!(&(cursor, bytes_before)).map_err(|e| e.to_string())?;
128+
let response = self.call_query("data_fetch", &args).await?;
123129
Decode!(response.as_slice(), Result<(String, Vec<u8>), String>)
124130
.map_err(|e| e.to_string())?
125131
}

cli/src/main.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use chrono::DateTime;
1010
use dcc_common::{
1111
account_balance_get_as_string, amount_as_string, cursor_from_data, refresh_caches_from_ledger,
1212
zlib_compress, Account, CursorDirection, DccIdentity, FundsTransfer, LedgerCursor,
13-
NodeProviderProfile, UpdateProfilePayload, LABEL_DC_TOKEN_TRANSFER,
13+
NodeProviderProfile, UpdateProfilePayload, DATA_PULL_BYTES_BEFORE_LEN, LABEL_DC_TOKEN_TRANSFER,
1414
};
1515
use decent_cloud::ledger_canister_client::LedgerCanister;
1616
use decent_cloud_canister::DC_TOKEN_TRANSFER_FEE_E9S;
@@ -308,8 +308,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
308308
.expect("Could not get home directory")
309309
.join(".dcc/ledger/main.bin"),
310310
};
311-
let push_auth = arg_matches.get_flag("push-authorize");
312-
let push = arg_matches.get_flag("push");
311+
let push_auth = arg_matches.get_flag("data-push-authorize");
312+
let push = arg_matches.get_flag("data-push");
313313
if push_auth || push {
314314
let local_identity = match local_identity {
315315
Some(ident) => ident.to_string(),
@@ -322,7 +322,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
322322
let ic_auth = dcc_to_ic_auth(&dcc_ident);
323323
let canister = ledger_canister(ic_auth).await?;
324324
let args = Encode!(&()).map_err(|e| e.to_string())?;
325-
let result = canister.call_update("push_auth", &args).await?;
325+
let result = canister.call_update("data_push_auth", &args).await?;
326326
let response =
327327
Decode!(&result, Result<String, String>).map_err(|e| e.to_string())??;
328328

@@ -333,7 +333,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
333333
let ic_auth = dcc_to_ic_auth(&dcc_ident);
334334
let canister = ledger_canister(ic_auth).await?;
335335

336-
return push_ledger_data(&canister, local_ledger_path).await;
336+
return ledger_data_push(&canister, local_ledger_path).await;
337337
}
338338

339339
let canister_function = match arg_matches.get_one::<String>("canister_function") {
@@ -371,9 +371,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
371371
let canister = ledger_canister(None).await?;
372372
println!("{}", canister.init_ledger_map().await?);
373373
}
374-
"fetch" => {
374+
"data_fetch" | "fetch" => {
375375
let canister = ledger_canister(None).await?;
376-
fetch_ledger_data(&canister, local_ledger_path).await?;
376+
ledger_data_fetch(&canister, local_ledger_path).await?;
377377
println!("Done fetching data from the Ledger canister");
378378
}
379379
"metadata" => {
@@ -488,7 +488,7 @@ fn dcc_to_ic_auth(dcc_identity: &DccIdentity) -> Option<BasicIdentity> {
488488
})
489489
}
490490

491-
async fn fetch_ledger_data(
491+
async fn ledger_data_fetch(
492492
ledger_canister: &LedgerCanister,
493493
local_ledger_path: PathBuf,
494494
) -> Result<(), Box<dyn std::error::Error>> {
@@ -510,12 +510,23 @@ async fn fetch_ledger_data(
510510
)
511511
};
512512

513+
let bytes_before = if cursor_local.position > DATA_PULL_BYTES_BEFORE_LEN as u64 {
514+
let mut buf = vec![0u8; DATA_PULL_BYTES_BEFORE_LEN as usize];
515+
persistent_storage_read(
516+
cursor_local.position - DATA_PULL_BYTES_BEFORE_LEN as u64,
517+
&mut buf,
518+
)?;
519+
Some(buf)
520+
} else {
521+
None
522+
};
523+
513524
println!(
514525
"Fetching data from the Ledger canister, with local cursor: {}",
515526
cursor_local
516527
);
517528
let (cursor_remote, data) = ledger_canister
518-
.fetch(Some(cursor_local.to_request_string()))
529+
.data_fetch(Some(cursor_local.to_request_string()), bytes_before)
519530
.await?;
520531
let cursor_remote = LedgerCursor::new_from_string(cursor_remote);
521532
let offset_remote = cursor_remote.position;
@@ -571,7 +582,7 @@ async fn get_ledger_metadata(ledger_canister: &LedgerCanister) -> HashMap<String
571582
.collect()
572583
}
573584

574-
pub async fn push_ledger_data(
585+
pub async fn ledger_data_push(
575586
ledger_canister: &LedgerCanister,
576587
local_ledger_path: PathBuf,
577588
) -> Result<(), Box<dyn std::error::Error>> {
@@ -619,7 +630,7 @@ pub async fn push_ledger_data(
619630
buf_size, position,
620631
);
621632
let args = Encode!(&cursor_push.to_urlenc_string(), &buf).map_err(|e| e.to_string())?;
622-
let result = ledger_canister.call_update("push", &args).await?;
633+
let result = ledger_canister.call_update("data_push", &args).await?;
623634
let result = Decode!(&result, Result<String, String>).map_err(|e| e.to_string())??;
624635
println!("Response from pushing at position {}: {}", position, result);
625636
}

common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub const MEMO_BYTES_MAX: usize = 32;
7979
/// Reduction of reputations for all accounts, based on time (per block), in parts per million
8080
pub const REPUTATION_AGING_PPM: u64 = 1_000;
8181
pub const REWARD_HALVING_AFTER_BLOCKS: u64 = 210_000; // halve the rewards every 210000 reward distributions
82+
pub const DATA_PULL_BYTES_BEFORE_LEN: u16 = 16; // How many bytes before the pulled data should be compared as a quick sanity check
8283

8384
// Default first block's time
8485
// Calculated with:

ic-canister/decent_cloud.did

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,9 @@ service : {
390390
get_data_certificate : () -> (DataCertificate) query;
391391

392392
// Synchronization (pushing and pulling) of the ledger data
393-
fetch: (cursor: opt text) -> (ResultData) query;
394-
push_auth: () -> (ResultString);
395-
push: (cursor: text, data: vec nat8) -> (ResultString);
393+
data_fetch: (cursor: opt text, bytes_before: opt vec nat8) -> (ResultData) query;
394+
data_push_auth: () -> (ResultString);
395+
data_push: (cursor: text, data: vec nat8) -> (ResultString);
396396
metadata: () -> (vec record { text; MetadataValue; }) query;
397397

398398
// Debugging and troubleshooting

ic-canister/src/canister_backend/generic.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use dcc_common::{
77
np_registration_fee_e9s, refresh_caches_from_ledger, reputation_get, reward_e9s_per_block,
88
reward_e9s_per_block_recalculate, rewards_applied_np_count, rewards_distribute,
99
rewards_pending_e9s, set_test_config, FundsTransfer, LedgerCursor, BLOCK_INTERVAL_SECS,
10-
CACHE_TXS_NUM_COMMITTED, LABEL_DC_TOKEN_TRANSFER, LABEL_NP_CHECK_IN, LABEL_NP_PROFILE,
11-
LABEL_NP_REGISTER, LABEL_REWARD_DISTRIBUTION, LABEL_USER_REGISTER,
10+
CACHE_TXS_NUM_COMMITTED, DATA_PULL_BYTES_BEFORE_LEN, LABEL_DC_TOKEN_TRANSFER,
11+
LABEL_NP_CHECK_IN, LABEL_NP_PROFILE, LABEL_NP_REGISTER, LABEL_REWARD_DISTRIBUTION,
12+
LABEL_USER_REGISTER,
1213
};
1314
use ic_cdk::println;
1415
use icrc_ledger_types::icrc::generic_metadata_value::MetadataValue;
@@ -241,7 +242,10 @@ pub(crate) fn _node_provider_list_checked_in() -> Result<Vec<String>, String> {
241242
})
242243
}
243244

244-
pub(crate) fn _fetch(cursor: Option<String>) -> Result<(String, Vec<u8>), String> {
245+
pub(crate) fn _data_fetch(
246+
cursor: Option<String>,
247+
bytes_before: Option<Vec<u8>>,
248+
) -> Result<(String, Vec<u8>), String> {
245249
LEDGER_MAP.with(|ledger| {
246250
let req_cursor = LedgerCursor::new_from_string(cursor.unwrap_or_default());
247251
let req_position_start = req_cursor.position;
@@ -258,6 +262,23 @@ pub(crate) fn _fetch(cursor: Option<String>) -> Result<(String, Vec<u8>), String
258262
if local_cursor.response_bytes == 0 {
259263
return Ok((local_cursor.to_urlenc_string(), vec![]));
260264
}
265+
if let Some(bytes_before) = bytes_before {
266+
if local_cursor.position > DATA_PULL_BYTES_BEFORE_LEN as u64 {
267+
let mut buf_bytes_before = vec![0u8; DATA_PULL_BYTES_BEFORE_LEN as usize];
268+
persistent_storage_read(
269+
local_cursor.position - DATA_PULL_BYTES_BEFORE_LEN as u64,
270+
&mut buf_bytes_before,
271+
)
272+
.map_err(|e| e.to_string())?;
273+
if bytes_before != buf_bytes_before {
274+
return Err(format!(
275+
"{} bytes before position {} does not match",
276+
DATA_PULL_BYTES_BEFORE_LEN, local_cursor.position
277+
));
278+
}
279+
}
280+
}
281+
261282
let mut buf = vec![0u8; local_cursor.response_bytes as usize];
262283
persistent_storage_read(local_cursor.position, &mut buf).map_err(|e| e.to_string())?;
263284
info!(
@@ -268,7 +289,7 @@ pub(crate) fn _fetch(cursor: Option<String>) -> Result<(String, Vec<u8>), String
268289
})
269290
}
270291

271-
pub(crate) fn _push_auth() -> Result<String, String> {
292+
pub(crate) fn _data_push_auth() -> Result<String, String> {
272293
// If LEDGER_MAP is currently empty and there is no authorized pusher,
273294
// set the authorized pusher to the caller.
274295
LEDGER_MAP.with(|ledger| {
@@ -299,7 +320,7 @@ pub(crate) fn _push_auth() -> Result<String, String> {
299320
})
300321
}
301322

302-
pub(crate) fn _push(cursor: String, data: Vec<u8>) -> Result<String, String> {
323+
pub(crate) fn _data_push(cursor: String, data: Vec<u8>) -> Result<String, String> {
303324
let caller = ic_cdk::api::caller();
304325
let authorized_pusher = AUTHORIZED_PUSHER.with(|authorized_pusher| *authorized_pusher.borrow());
305326

ic-canister/src/canister_endpoints/generic.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,21 @@ fn node_provider_list_checked_in() -> Result<Vec<String>, String> {
8787
}
8888

8989
#[ic_cdk::query]
90-
fn fetch(cursor: Option<String>) -> Result<(String, Vec<u8>), String> {
91-
_fetch(cursor)
90+
fn data_fetch(
91+
cursor: Option<String>,
92+
bytes_before: Option<Vec<u8>>,
93+
) -> Result<(String, Vec<u8>), String> {
94+
_data_fetch(cursor, bytes_before)
9295
}
9396

9497
#[ic_cdk::update]
95-
fn push_auth() -> Result<String, String> {
96-
_push_auth()
98+
fn data_push_auth() -> Result<String, String> {
99+
_data_push_auth()
97100
}
98101

99102
#[ic_cdk::update]
100-
fn push(cursor: String, data: Vec<u8>) -> Result<String, String> {
101-
_push(cursor, data)
103+
fn data_push(cursor: String, data: Vec<u8>) -> Result<String, String> {
104+
_data_push(cursor, data)
102105
}
103106

104107
#[ic_cdk::query]

0 commit comments

Comments
 (0)