Skip to content

Commit 0c5ed7b

Browse files
committed
Move upgrade logic to kernel
1 parent b341d4c commit 0c5ed7b

File tree

7 files changed

+57
-93
lines changed

7 files changed

+57
-93
lines changed

fvm/src/call_manager/default.rs

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use fvm_shared::econ::TokenAmount;
1212
use fvm_shared::error::{ErrorNumber, ExitCode};
1313
use fvm_shared::event::StampedEvent;
1414
use fvm_shared::sys::BlockId;
15-
use fvm_shared::upgrade::UpgradeInfo;
1615
use fvm_shared::{ActorID, MethodNum, METHOD_SEND};
1716
use num_traits::Zero;
1817

@@ -167,7 +166,7 @@ where
167166
&mut self.limits
168167
}
169168

170-
fn send<K>(
169+
fn call_actor<K>(
171170
&mut self,
172171
from: ActorID,
173172
to: Address,
@@ -405,63 +404,6 @@ where
405404
Ok(())
406405
}
407406

408-
fn upgrade_actor<K: Kernel<CallManager = Self>>(
409-
&mut self,
410-
caller: ActorID,
411-
actor_id: ActorID,
412-
new_code_cid: Cid,
413-
params: Option<Block>,
414-
) -> Result<InvocationResult> {
415-
let origin = self.origin;
416-
417-
let state = self
418-
.state_tree_mut()
419-
.get_actor(actor_id)?
420-
.ok_or_else(|| syscall_error!(NotFound; "actor not found: {}", actor_id))?;
421-
422-
// store the code cid of the calling actor before running the upgrade entrypoint
423-
// in case it was changed (which could happen if the target upgrade entrypoint
424-
// sent a message to this actor which in turn called upgrade)
425-
let code = state.code;
426-
427-
// update the code cid of the actor to new_code_cid
428-
self.state_tree_mut().set_actor(
429-
origin,
430-
ActorState::new(
431-
new_code_cid,
432-
state.state,
433-
state.balance,
434-
state.sequence,
435-
None,
436-
),
437-
);
438-
439-
// run the upgrade entrypoint
440-
let result = self.send::<K>(
441-
caller,
442-
Address::new_id(actor_id),
443-
Entrypoint::Upgrade(UpgradeInfo { old_code_cid: code }),
444-
params,
445-
&TokenAmount::zero(),
446-
None,
447-
false,
448-
)?;
449-
450-
if result.exit_code == ExitCode::OK {
451-
// after running the upgrade, our code cid must not have changed
452-
let code_after_upgrade = self
453-
.state_tree_mut()
454-
.get_actor(actor_id)?
455-
.ok_or_else(|| syscall_error!(NotFound; "actor not found: {}", actor_id))?
456-
.code;
457-
if code != code_after_upgrade {
458-
return Err(syscall_error!(Forbidden; "re-entrant upgrade detected").into());
459-
}
460-
}
461-
462-
Ok(result)
463-
}
464-
465407
fn append_event(&mut self, evt: StampedEvent) {
466408
self.events.append_event(evt)
467409
}

fvm/src/call_manager/mod.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub trait CallManager: 'static {
6464
/// Send a message. The type parameter `K` specifies the the _kernel_ on top of which the target
6565
/// actor should execute.
6666
#[allow(clippy::too_many_arguments)]
67-
fn send<K: Kernel<CallManager = Self>>(
67+
fn call_actor<K: Kernel<CallManager = Self>>(
6868
&mut self,
6969
from: ActorID,
7070
to: Address,
@@ -118,16 +118,6 @@ pub trait CallManager: 'static {
118118
delegated_address: Option<Address>,
119119
) -> Result<()>;
120120

121-
fn upgrade_actor<K>(
122-
&mut self,
123-
caller: ActorID,
124-
actor_id: ActorID,
125-
new_code_cid: Cid,
126-
params: Option<kernel::Block>,
127-
) -> Result<InvocationResult>
128-
where
129-
K: Kernel<CallManager = Self>;
130-
131121
/// Resolve an address into an actor ID, charging gas as appropriate.
132122
fn resolve_address(&self, address: &Address) -> Result<Option<ActorID>>;
133123

fvm/src/executor/default.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ where
144144
let result = cm.with_transaction(|cm| {
145145
// Invoke the message. We charge for the return value internally if the call-stack depth
146146
// is 1.
147-
cm.send::<K>(
147+
cm.call_actor::<K>(
148148
sender_id,
149149
msg.to,
150150
Entrypoint::Invoke(msg.method_num),

fvm/src/kernel/default.rs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use fvm_shared::event::{ActorEvent, Entry, Flags};
2020
use fvm_shared::piece::{zero_piece_commitment, PaddedPieceSize};
2121
use fvm_shared::sector::{RegisteredPoStProof, SectorInfo};
2222
use fvm_shared::sys::out::vm::ContextFlags;
23+
use fvm_shared::upgrade::UpgradeInfo;
2324
use fvm_shared::{commcid, ActorID};
2425
use lazy_static::lazy_static;
2526
use multihash::MultihashDigest;
@@ -139,7 +140,7 @@ where
139140

140141
// Send.
141142
let result = self.call_manager.with_transaction(|cm| {
142-
cm.send::<K>(
143+
cm.call_actor::<K>(
143144
from,
144145
*recipient,
145146
Entrypoint::Invoke(method),
@@ -873,7 +874,7 @@ where
873874
.create_actor(code_id, actor_id, delegated_address)
874875
}
875876

876-
fn upgrade_actor(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result<u32> {
877+
fn upgrade_actor<K: Kernel>(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result<u32> {
877878
if self.read_only {
878879
return Err(
879880
syscall_error!(ReadOnly, "upgrade_actor cannot be called while read-only").into(),
@@ -888,7 +889,52 @@ where
888889
};
889890

890891
let result = self.call_manager.with_transaction(|cm| {
891-
cm.upgrade_actor::<Self>(self.caller, self.actor_id, new_code_cid, params)
892+
let origin = cm.origin();
893+
894+
let state = cm
895+
.get_actor(self.actor_id)?
896+
.ok_or_else(|| syscall_error!(NotFound; "actor not found"))?;
897+
898+
// store the code cid of the calling actor before running the upgrade entrypoint
899+
// in case it was changed (which could happen if the target upgrade entrypoint
900+
// sent a message to this actor which in turn called upgrade)
901+
let code = state.code;
902+
903+
// update the code cid of the actor to new_code_cid
904+
cm.set_actor(
905+
origin,
906+
ActorState::new(
907+
new_code_cid,
908+
state.state,
909+
state.balance,
910+
state.sequence,
911+
None,
912+
),
913+
)?;
914+
915+
// run the upgrade entrypoint
916+
let result = cm.call_actor::<Self>(
917+
self.caller,
918+
Address::new_id(self.actor_id),
919+
Entrypoint::Upgrade(UpgradeInfo { old_code_cid: code }),
920+
params,
921+
&TokenAmount::from_whole(0),
922+
None,
923+
false,
924+
)?;
925+
926+
if result.exit_code == ExitCode::OK {
927+
// after running the upgrade, our code cid must not have changed
928+
let code_after_upgrade = cm
929+
.get_actor(self.actor_id)?
930+
.ok_or_else(|| syscall_error!(NotFound; "actor not found"))?
931+
.code;
932+
if code != code_after_upgrade {
933+
return Err(syscall_error!(Forbidden; "re-entrant upgrade detected").into());
934+
}
935+
}
936+
937+
Ok(result)
892938
});
893939

894940
match result {

fvm/src/kernel/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub trait ActorOps {
209209
delegated_address: Option<Address>,
210210
) -> Result<()>;
211211

212-
fn upgrade_actor(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result<u32>;
212+
fn upgrade_actor<K: Kernel>(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result<u32>;
213213

214214
/// Installs actor code pointed by cid
215215
#[cfg(feature = "m2-native")]

fvm/src/syscalls/actor.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,14 @@ pub fn create_actor(
109109
context.kernel.create_actor(typ, actor_id, addr)
110110
}
111111

112-
#[allow(dead_code)]
113-
pub fn upgrade_actor(
114-
context: Context<'_, impl Kernel>,
112+
pub fn upgrade_actor<K: Kernel>(
113+
context: Context<'_, K>,
115114
new_code_cid_off: u32,
116115
params_id: u32,
117116
) -> Result<u32> {
118117
let cid = context.memory.read_cid(new_code_cid_off)?;
119118

120-
context.kernel.upgrade_actor(cid, params_id)
119+
context.kernel.upgrade_actor::<K>(cid, params_id)
121120
}
122121

123122
pub fn get_builtin_actor_type(

fvm/tests/dummy.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl CallManager for DummyCallManager {
274274
}
275275
}
276276

277-
fn send<K: Kernel<CallManager = Self>>(
277+
fn call_actor<K: Kernel<CallManager = Self>>(
278278
&mut self,
279279
_from: fvm_shared::ActorID,
280280
_to: Address,
@@ -400,17 +400,4 @@ impl CallManager for DummyCallManager {
400400
) -> fvm::kernel::Result<()> {
401401
todo!()
402402
}
403-
404-
fn upgrade_actor<K>(
405-
&mut self,
406-
_caller: ActorID,
407-
_actor_id: ActorID,
408-
_new_code_cid: Cid,
409-
_params: Option<kernel::Block>,
410-
) -> kernel::Result<InvocationResult>
411-
where
412-
K: Kernel<CallManager = Self>,
413-
{
414-
todo!()
415-
}
416403
}

0 commit comments

Comments
 (0)