Skip to content

Commit d111b40

Browse files
authored
chore: remove legacy struct from mpc node and tee context post contract upgrade (#4224)
1 parent 41f86dd commit d111b40

6 files changed

Lines changed: 86 additions & 129 deletions

File tree

Cargo.lock

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

crates/chain-gateway/src/mock.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use near_account_id::AccountId;
44
use near_contract_transport::{BlockHeight, ObservedState};
55
use near_contract_transport::{ViewArgs, ViewContract};
66
use near_indexer::near_primitives::transaction::SignedTransaction;
7+
use std::collections::HashMap;
78
use std::sync::{Arc, Mutex};
89
use std::time::Duration;
910
use thiserror::Error;
@@ -20,6 +21,7 @@ pub struct MockChainState {
2021

2122
pub struct MockViewState {
2223
pub response: Result<ObservedState, MockError>,
24+
pub responses_by_method: HashMap<String, Result<ObservedState, MockError>>,
2325
pub submitted: Vec<Call>,
2426
}
2527

@@ -50,6 +52,15 @@ impl MockChainState {
5052
inner.response = value;
5153
}
5254

55+
pub fn set_view_response_for_method(
56+
&self,
57+
method_name: impl Into<String>,
58+
value: Result<ObservedState, MockError>,
59+
) {
60+
let mut inner = self.view_state.lock().unwrap();
61+
inner.responses_by_method.insert(method_name.into(), value);
62+
}
63+
5364
/// Wait for the next view_contract call (polls submitted.len() every 10ms).
5465
pub async fn await_next_view_call(&self, max_wait_duration: Duration) -> Result<(), MockError> {
5566
tokio::time::timeout(max_wait_duration, self.read_notify.notified())
@@ -118,6 +129,7 @@ impl MockChainStateBuilder {
118129
sync_response: Arc::new(Mutex::new(self.sync_response)),
119130
view_state: Arc::new(Mutex::new(MockViewState {
120131
response: self.view_response,
132+
responses_by_method: HashMap::new(),
121133
submitted: Vec::new(),
122134
})),
123135
read_notify: Arc::new(Notify::new()),
@@ -148,12 +160,16 @@ impl ViewContract for MockChainState {
148160
view_args: ViewArgs,
149161
) -> Result<ObservedState, Self::Error> {
150162
let mut inner = self.view_state.lock().unwrap();
163+
let response = inner
164+
.responses_by_method
165+
.get(&view_args.method_name)
166+
.unwrap_or(&inner.response)
167+
.clone();
151168
inner.submitted.push(Call {
152169
contract_id: contract_id.clone(),
153170
method_name: view_args.method_name,
154171
args: view_args.args,
155172
});
156-
let response = inner.response.clone();
157173
drop(inner);
158174
self.read_notify.notify_waiters();
159175
response

crates/node/src/indexer.rs

Lines changed: 4 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{indexer::migrations::ContractMigrationInfo, migration_service::types
55
use self::stats::IndexerStats;
66
use anyhow::Context;
77
use handler::ChainBlockUpdate;
8-
use mpc_primitives::hash::{LauncherDockerComposeHash, NodeImageHash};
8+
use mpc_primitives::hash::LauncherDockerComposeHash;
99
use near_account_id::AccountId;
1010
use near_async::{
1111
messaging::CanSendAsync, multithread::MultithreadRuntimeHandle, tokio::TokioRuntimeHandle,
@@ -47,13 +47,7 @@ pub mod types;
4747
#[cfg(test)]
4848
pub mod fake;
4949

50-
// TODO(#3751): drop this struct after upgrading the contract.
51-
#[derive(Debug, PartialEq, Deserialize)]
52-
#[serde(untagged)]
53-
enum AllowedDockerImageHashesResponse {
54-
WithExpiry(Vec<dtos::AllowedMpcDockerImageHash>),
55-
Legacy(Vec<NodeImageHash>),
56-
}
50+
type AllowedDockerImageHashesResponse = Vec<dtos::AllowedMpcDockerImageHash>;
5751

5852
pub(crate) struct IndexerState {
5953
/// For querying blockchain state.
@@ -334,21 +328,10 @@ impl IndexerViewClient {
334328
&self,
335329
mpc_contract_id: AccountId,
336330
) -> anyhow::Result<(u64, Vec<dtos::AllowedMpcDockerImageHash>)> {
337-
let (block_height, response): (u64, AllowedDockerImageHashesResponse) = self
331+
let (block_height, entries): (u64, AllowedDockerImageHashesResponse) = self
338332
.get_mpc_state(mpc_contract_id, ALLOWED_DOCKER_IMAGE_HASHES)
339333
.await?;
340334

341-
// TODO(#3751): drop this logic after upgrading the contract.
342-
let entries = match response {
343-
AllowedDockerImageHashesResponse::WithExpiry(entries) => entries,
344-
AllowedDockerImageHashesResponse::Legacy(hashes) => hashes
345-
.into_iter()
346-
.map(|image_hash| dtos::AllowedMpcDockerImageHash {
347-
image_hash,
348-
expiry_timestamp_seconds: None,
349-
})
350-
.collect(),
351-
};
352335
Ok((block_height, entries))
353336
}
354337
pub(crate) async fn get_mpc_allowed_launcher_compose_hashes(
@@ -592,42 +575,7 @@ pub struct IndexerAPI<TransactionSender> {
592575
#[cfg(test)]
593576
#[expect(non_snake_case)]
594577
mod tests {
595-
use super::{
596-
AllowedDockerImageHashesResponse, BlockHeight, REQUIRED_STABLE_POLLS, SyncProgress,
597-
};
598-
use assert_matches::assert_matches;
599-
use mpc_primitives::hash::NodeImageHash;
600-
601-
#[test]
602-
fn allowed_docker_image_hashes_response__should_deserialize_with_expiry_objects() {
603-
let json = r#"[
604-
{ "image_hash": "1111111111111111111111111111111111111111111111111111111111111111", "expiry_timestamp_seconds": 42 },
605-
{ "image_hash": "2222222222222222222222222222222222222222222222222222222222222222", "expiry_timestamp_seconds": null }
606-
]"#;
607-
let response: AllowedDockerImageHashesResponse = serde_json::from_str(json).unwrap();
608-
assert_matches!(response, AllowedDockerImageHashesResponse::WithExpiry(entries) if entries.len() == 2);
609-
}
610-
611-
#[test]
612-
fn allowed_docker_image_hashes_response__should_deserialize_legacy_bare_hashes() {
613-
// Given: the shape returned by contracts predating expiry reporting.
614-
let json = r#"[
615-
"1111111111111111111111111111111111111111111111111111111111111111",
616-
"2222222222222222222222222222222222222222222222222222222222222222"
617-
]"#;
618-
619-
// When
620-
let response: AllowedDockerImageHashesResponse = serde_json::from_str(json).unwrap();
621-
622-
// Then
623-
assert_eq!(
624-
response,
625-
AllowedDockerImageHashesResponse::Legacy(vec![
626-
NodeImageHash::from([0x11; 32]),
627-
NodeImageHash::from([0x22; 32]),
628-
])
629-
);
630-
}
578+
use super::{BlockHeight, REQUIRED_STABLE_POLLS, SyncProgress};
631579

632580
fn first_caught_up_poll(samples: &[(bool, BlockHeight)]) -> Option<usize> {
633581
let mut progress = SyncProgress::default();

crates/node/src/tee/image_expiry_metrics.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,19 @@ pub fn update_own_image_hash_gauges(
2626
/// - last value indicates expiry timestamp (-1 if no expiry timestamp is given,
2727
/// 0 if `current_image` is not allowed)
2828
///
29-
/// Expects `allowed_images` to be newest-first, as returned by the contract view.
29+
/// Expects the newest allowed image to be the only one the contract reports without
30+
/// an expiry timestamp.
3031
fn infer_image_status(
3132
current_image: &NodeImageHash,
3233
allowed_images: &[AllowedMpcDockerImageHash],
3334
) -> (bool, bool, i64) {
34-
// TODO(#3751): simplify this function after updating the contract
35-
let is_most_recent = allowed_images
36-
.first()
37-
.is_some_and(|newest| newest.image_hash == *current_image);
38-
3935
match allowed_images
4036
.iter()
4137
.find(|entry| entry.image_hash == *current_image)
4238
{
4339
Some(entry) => match entry.expiry_timestamp_seconds {
44-
Some(expires_at) => (
45-
true,
46-
is_most_recent,
47-
i64::try_from(expires_at).unwrap_or(i64::MAX),
48-
),
49-
None => (true, is_most_recent, NO_EXPIRY),
40+
Some(expires_at) => (true, false, i64::try_from(expires_at).unwrap_or(i64::MAX)),
41+
None => (true, true, NO_EXPIRY),
5042
},
5143
None => (false, false, 0),
5244
}

crates/tee-context/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ near-contract-transport = { workspace = true }
1111
near-mpc-contract-interface = { workspace = true, features = ["client"] }
1212

1313
near-account-id = { workspace = true }
14-
serde = { workspace = true }
1514
thiserror = { workspace = true }
1615
tokio = { workspace = true }
1716
tokio-util = { workspace = true }

0 commit comments

Comments
 (0)