|
1 | 1 | use fil_actors_evm_shared::address::EthAddress;
|
2 | 2 | use fil_actors_runtime::{
|
3 |
| - actor_dispatch_unrestricted, actor_error, ActorError, AsActorError, EAM_ACTOR_ADDR, |
| 3 | + actor_dispatch_unrestricted, actor_error, ActorError, AsActorError, WithCodec, EAM_ACTOR_ADDR, |
4 | 4 | INIT_ACTOR_ADDR,
|
5 | 5 | };
|
6 | 6 | use fvm_ipld_blockstore::Blockstore;
|
7 | 7 | use fvm_ipld_encoding::ipld_block::IpldBlock;
|
8 |
| -use fvm_ipld_encoding::BytesSer; |
| 8 | +use fvm_ipld_encoding::{BytesSer, DAG_CBOR}; |
9 | 9 | use fvm_shared::address::Address;
|
10 | 10 | use fvm_shared::econ::TokenAmount;
|
11 | 11 | use fvm_shared::error::ExitCode;
|
@@ -206,14 +206,20 @@ impl EvmContractActor {
|
206 | 206 | initialize_evm_contract(&mut System::resurrect(rt)?, params.creator, params.initcode.into())
|
207 | 207 | }
|
208 | 208 |
|
| 209 | + /// Invoke the contract with some _alternative_ bytecode. This can only be called by the |
| 210 | + /// contract itself and is used to implement the EVM's DELEGATECALL opcode. |
| 211 | + /// |
| 212 | + /// This method expects DAG_CBOR encoded parameters (the linked `params.code` needs to be |
| 213 | + /// reachable). |
209 | 214 | pub fn invoke_contract_delegate<RT>(
|
210 | 215 | rt: &RT,
|
211 |
| - params: DelegateCallParams, |
| 216 | + params: WithCodec<DelegateCallParams, DAG_CBOR>, |
212 | 217 | ) -> Result<DelegateCallReturn, ActorError>
|
213 | 218 | where
|
214 | 219 | RT: Runtime,
|
215 | 220 | RT::Blockstore: Clone,
|
216 | 221 | {
|
| 222 | + let params = params.0; |
217 | 223 | rt.validate_immediate_caller_is(&[rt.message().receiver()])?;
|
218 | 224 |
|
219 | 225 | let mut system = System::load(rt).map_err(|e| {
|
@@ -281,15 +287,17 @@ impl EvmContractActor {
|
281 | 287 |
|
282 | 288 | /// Returns the contract's EVM bytecode, or `None` if the contract has been deleted (has called
|
283 | 289 | /// SELFDESTRUCT).
|
284 |
| - pub fn bytecode(rt: &impl Runtime) -> Result<BytecodeReturn, ActorError> { |
| 290 | + /// |
| 291 | + /// Return value is "dag cbor" as we need the linked bytecode (if present) to be reachable. |
| 292 | + pub fn bytecode(rt: &impl Runtime) -> Result<WithCodec<BytecodeReturn, DAG_CBOR>, ActorError> { |
285 | 293 | // Any caller can fetch the bytecode of a contract; this is now EXT* opcodes work.
|
286 | 294 | rt.validate_immediate_caller_accept_any()?;
|
287 | 295 |
|
288 | 296 | let state: State = rt.state()?;
|
289 | 297 | if is_dead(rt, &state) {
|
290 |
| - Ok(BytecodeReturn { code: None }) |
| 298 | + Ok(BytecodeReturn { code: None }.into()) |
291 | 299 | } else {
|
292 |
| - Ok(BytecodeReturn { code: Some(state.bytecode) }) |
| 300 | + Ok(BytecodeReturn { code: Some(state.bytecode) }.into()) |
293 | 301 | }
|
294 | 302 | }
|
295 | 303 |
|
@@ -417,6 +425,6 @@ impl ActorCode for EvmContractActor {
|
417 | 425 | GetStorageAt => storage_at,
|
418 | 426 | InvokeContractDelegate => invoke_contract_delegate,
|
419 | 427 | Resurrect => resurrect,
|
420 |
| - _ => handle_filecoin_method [raw], |
| 428 | + _ => handle_filecoin_method, |
421 | 429 | }
|
422 | 430 | }
|
0 commit comments