Skip to content

Commit 23265b3

Browse files
gregorydemayTHLOIDX GitHub Automation
authored
refactor(ckbtc): Generic events (#7991)
Refactor the ckBTC event log to be generic over the type of events stored, so that the ckDOGE minter, that reuses code from the ckBTC minter can have dedicated events. Quite a few ckBTC events are only there for backwards-compatibility reasons or are not relevant for the ckDOGE minter (e.g. events related to checking whether UTXOs or addresses are tainted). This PR is pure refactoring and does not change the behaviour of the ckBTC or ckDOGE minter. It only allows to have 2 implementations, which are currently identical, on how to record and replay events. The next PR will change the ckDOGE implementation to have dedicated events. 1. #7991 2. #8035 --------- Co-authored-by: Thomas Locher <[email protected]> Co-authored-by: IDX GitHub Automation <[email protected]>
1 parent c83b503 commit 23265b3

File tree

19 files changed

+557
-357
lines changed

19 files changed

+557
-357
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rs/bitcoin/ckbtc/agent/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use candid::{CandidType, Deserialize, Principal};
22
use ic_agent::Agent;
33
use ic_ckbtc_minter::queries::{EstimateFeeArg, RetrieveBtcStatusRequest, WithdrawalFee};
44
use ic_ckbtc_minter::state::RetrieveBtcStatus;
5-
use ic_ckbtc_minter::state::eventlog::{Event, GetEventsArg};
5+
use ic_ckbtc_minter::state::eventlog::{CkBtcMinterEvent, GetEventsArg};
66
use ic_ckbtc_minter::updates::{
77
get_btc_address::GetBtcAddressArgs,
88
retrieve_btc::{RetrieveBtcArgs, RetrieveBtcError, RetrieveBtcOk},
@@ -135,7 +135,7 @@ impl CkBtcMinterAgent {
135135
&self,
136136
start: u64,
137137
length: u64,
138-
) -> Result<Vec<Event>, CkBtcMinterAgentError> {
138+
) -> Result<Vec<CkBtcMinterEvent>, CkBtcMinterAgentError> {
139139
self.query("get_events", GetEventsArg { start, length })
140140
.await
141141
}

rs/bitcoin/ckbtc/minter/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::collections::{BTreeMap, BTreeSet};
1919
use std::time::Duration;
2020

2121
use crate::fees::{BitcoinFeeEstimator, FeeEstimator};
22+
use crate::state::eventlog::{CkBtcEventLogger, EventLogger};
2223
use crate::state::utxos::UtxoSet;
2324
use crate::state::{CkBtcMinterState, mutate_state, read_state};
2425
use crate::updates::get_btc_address;
@@ -1584,6 +1585,9 @@ pub trait CanisterRuntime {
15841585
/// Type used to estimate fees.
15851586
type Estimator: FeeEstimator;
15861587

1588+
/// Type used for events recording of state changes.
1589+
type EventLogger: EventLogger;
1590+
15871591
/// Returns the caller of the current call.
15881592
fn caller(&self) -> Principal {
15891593
ic_cdk::api::msg_caller()
@@ -1631,6 +1635,9 @@ pub trait CanisterRuntime {
16311635
/// How to estimate fees.
16321636
fn fee_estimator(&self, state: &CkBtcMinterState) -> Self::Estimator;
16331637

1638+
/// How to record and replay events.
1639+
fn event_logger(&self) -> Self::EventLogger;
1640+
16341641
/// Retrieves the current transaction fee percentiles.
16351642
async fn get_current_fee_percentiles(
16361643
&self,
@@ -1687,6 +1694,7 @@ pub struct IcCanisterRuntime {}
16871694
#[async_trait]
16881695
impl CanisterRuntime for IcCanisterRuntime {
16891696
type Estimator = BitcoinFeeEstimator;
1697+
type EventLogger = CkBtcEventLogger;
16901698

16911699
fn refresh_fee_percentiles_frequency(&self) -> Duration {
16921700
const ONE_HOUR: Duration = Duration::from_secs(3_600);
@@ -1697,6 +1705,10 @@ impl CanisterRuntime for IcCanisterRuntime {
16971705
BitcoinFeeEstimator::from_state(state)
16981706
}
16991707

1708+
fn event_logger(&self) -> Self::EventLogger {
1709+
CkBtcEventLogger
1710+
}
1711+
17001712
async fn get_current_fee_percentiles(
17011713
&self,
17021714
request: &GetCurrentFeePercentilesRequest,

rs/bitcoin/ckbtc/minter/src/lifecycle/upgrade.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::CanisterRuntime;
22
use crate::logs::Priority;
3-
use crate::state::eventlog::{EventType, replay};
3+
use crate::state::eventlog::{EventLogger, EventType};
44
use crate::state::invariants::CheckInvariantsImpl;
55
use crate::state::{Mode, replace_state};
6-
use crate::storage::{count_events, events, migrate_old_events_if_not_empty, record_event};
6+
use crate::storage::{count_events, migrate_old_events_if_not_empty, record_event};
77
use candid::{CandidType, Deserialize};
88
use canlog::log;
99
use ic_base_types::CanisterId;
@@ -84,9 +84,13 @@ pub fn post_upgrade<R: CanisterRuntime>(upgrade_args: Option<UpgradeArgs>, runti
8484
count_events()
8585
);
8686

87-
let state = replay::<CheckInvariantsImpl>(events()).unwrap_or_else(|e| {
88-
ic_cdk::trap(format!("[upgrade]: failed to replay the event log: {e:?}"))
89-
});
87+
let event_logger = runtime.event_logger();
88+
89+
let state = event_logger
90+
.replay::<CheckInvariantsImpl>(event_logger.events_iter())
91+
.unwrap_or_else(|e| {
92+
ic_cdk::trap(format!("[upgrade]: failed to replay the event log: {e:?}"))
93+
});
9094

9195
runtime.validate_config(&state);
9296

rs/bitcoin/ckbtc/minter/src/main.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ic_ckbtc_minter::lifecycle::upgrade::UpgradeArgs;
55
use ic_ckbtc_minter::lifecycle::{self, init::MinterArg};
66
use ic_ckbtc_minter::queries::{EstimateFeeArg, RetrieveBtcStatusRequest, WithdrawalFee};
77
use ic_ckbtc_minter::reimbursement::InvalidTransactionError;
8-
use ic_ckbtc_minter::state::eventlog::Event;
8+
use ic_ckbtc_minter::state::eventlog::CkBtcMinterEvent;
99
use ic_ckbtc_minter::state::{
1010
BtcRetrievalStatusV2, RetrieveBtcStatus, RetrieveBtcStatusV2, mutate_state, read_state,
1111
};
@@ -61,13 +61,19 @@ fn ok_or_die(result: Result<(), String>) {
6161
/// Checks that ckBTC minter state internally consistent.
6262
#[cfg(feature = "self_check")]
6363
fn check_invariants() -> Result<(), String> {
64-
use ic_ckbtc_minter::state::{eventlog::replay, invariants::CheckInvariantsImpl};
64+
use ic_ckbtc_minter::state::{
65+
eventlog::{CkBtcEventLogger, EventLogger},
66+
invariants::CheckInvariantsImpl,
67+
};
68+
69+
let events_logger = CkBtcEventLogger;
6570

6671
read_state(|s| {
6772
s.check_invariants()?;
6873

69-
let events: Vec<_> = storage::events().collect();
70-
let recovered_state = replay::<CheckInvariantsImpl>(events.clone().into_iter())
74+
let events: Vec<_> = events_logger.events_iter().collect();
75+
let recovered_state = events_logger
76+
.replay::<CheckInvariantsImpl>(events.clone().into_iter())
7177
.unwrap_or_else(|e| panic!("failed to replay log ({e:?}): {events:?}"));
7278

7379
recovered_state.check_invariants()?;
@@ -197,7 +203,7 @@ async fn get_canister_status() -> ic_cdk::management_canister::CanisterStatusRes
197203

198204
#[cfg(feature = "self_check")]
199205
#[update]
200-
async fn upload_events(events: Vec<Event>) {
206+
async fn upload_events(events: Vec<CkBtcMinterEvent>) {
201207
for event in events {
202208
storage::record_event(event.payload, &IC_CANISTER_RUNTIME);
203209
}
@@ -259,7 +265,7 @@ fn http_request(req: HttpRequest) -> HttpResponse {
259265
}
260266

261267
#[query]
262-
fn get_events(args: GetEventsArg) -> Vec<Event> {
268+
fn get_events(args: GetEventsArg) -> Vec<CkBtcMinterEvent> {
263269
const MAX_EVENTS_PER_QUERY: usize = 2000;
264270

265271
storage::events()

0 commit comments

Comments
 (0)