Skip to content

Commit f4e5573

Browse files
committed
Merge branch 'master' into next
2 parents 2fc00ef + 4f5449d commit f4e5573

File tree

19 files changed

+277
-113
lines changed

19 files changed

+277
-113
lines changed

actors/datacap/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub enum Method {
7070
DestroyExported = frc42_dispatch::method_hash!("Destroy"),
7171
NameExported = frc42_dispatch::method_hash!("Name"),
7272
SymbolExported = frc42_dispatch::method_hash!("Symbol"),
73-
GranularityExported = frc42_dispatch::method_hash!("GranularityExported"),
73+
GranularityExported = frc42_dispatch::method_hash!("Granularity"),
7474
TotalSupplyExported = frc42_dispatch::method_hash!("TotalSupply"),
7575
BalanceExported = frc42_dispatch::method_hash!("Balance"),
7676
TransferExported = frc42_dispatch::method_hash!("Transfer"),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# EVM Precompile Test Data
2+
3+
These data files come from [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) and are therefore licensed under the LGPLv3. However, they're not included in published crates (they're excluded by cargo) or build artifacts. They're only loaded at runtime by a few unit tests, and therefore trivially meet the requirements of the LGPL.

actors/evm/src/interpreter/precompiles/evm.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use std::ops::Range;
22

3-
use fil_actors_evm_shared::uints::{
4-
byteorder::{ByteOrder, LE},
5-
U256,
6-
};
3+
use fil_actors_evm_shared::uints::byteorder::{ByteOrder, LE};
4+
use fil_actors_evm_shared::uints::U256;
5+
76
use fil_actors_runtime::runtime::Runtime;
8-
use fvm_shared::crypto::{
9-
hash::SupportedHashes,
10-
signature::{SECP_SIG_LEN, SECP_SIG_MESSAGE_HASH_SIZE},
11-
};
7+
use fvm_shared::crypto::hash::SupportedHashes;
8+
use fvm_shared::crypto::signature::{SECP_SIG_LEN, SECP_SIG_MESSAGE_HASH_SIZE};
129
use num_traits::{One, Zero};
1310
use substrate_bn::{pairing_batch, AffineG1, AffineG2, Fq, Fq2, Fr, Group, Gt, G1, G2};
1411

actors/evm/src/interpreter/system.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,21 @@ use fvm_ipld_blockstore::Block;
88
use fvm_ipld_encoding::ipld_block::IpldBlock;
99
use fvm_ipld_encoding::CborStore;
1010
use fvm_ipld_kamt::HashedKey;
11-
use fvm_shared::{
12-
address::{Address, Payload},
13-
crypto::hash::SupportedHashes,
14-
econ::TokenAmount,
15-
error::{ErrorNumber, ExitCode},
16-
sys::SendFlags,
17-
MethodNum, Response, IPLD_RAW, METHOD_SEND,
18-
};
11+
use fvm_shared::address::{Address, Payload};
12+
use fvm_shared::crypto::hash::SupportedHashes;
13+
use fvm_shared::econ::TokenAmount;
14+
use fvm_shared::error::{ErrorNumber, ExitCode};
15+
use fvm_shared::sys::SendFlags;
16+
use fvm_shared::{MethodNum, Response, IPLD_RAW, METHOD_SEND};
1917
use multihash::Code;
2018

2119
use crate::state::{State, Tombstone};
2220
use crate::BytecodeHash;
2321

24-
use {
25-
cid::Cid,
26-
fil_actors_runtime::{runtime::Runtime, ActorError},
27-
fvm_ipld_blockstore::Blockstore,
28-
fvm_ipld_kamt::{AsHashedKey, Config as KamtConfig, Kamt},
29-
};
22+
use cid::Cid;
23+
use fil_actors_runtime::{runtime::Runtime, ActorError};
24+
use fvm_ipld_blockstore::Blockstore;
25+
use fvm_ipld_kamt::{AsHashedKey, Config as KamtConfig, Kamt};
3026

3127
// The Solidity compiler creates contiguous array item keys.
3228
// To prevent the tree from going very deep we use extensions,

actors/evm/src/lib.rs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use fil_actors_evm_shared::address::EthAddress;
22
use fil_actors_evm_shared::uints::U256;
3-
use fil_actors_runtime::{actor_error, AsActorError, EAM_ACTOR_ADDR, INIT_ACTOR_ADDR};
3+
use fil_actors_runtime::{actor_error, ActorError, AsActorError, EAM_ACTOR_ADDR, INIT_ACTOR_ADDR};
44
use fvm_ipld_blockstore::Blockstore;
55
use fvm_ipld_encoding::ipld_block::IpldBlock;
6-
use fvm_ipld_encoding::{strict_bytes, BytesDe, BytesSer};
6+
use fvm_ipld_encoding::{BytesDe, BytesSer};
77
use fvm_shared::address::Address;
88
use fvm_shared::econ::TokenAmount;
99
use fvm_shared::error::ExitCode;
1010

1111
use crate::interpreter::Outcome;
12+
use crate::interpreter::{execute, Bytecode, ExecutionState, System};
1213
use crate::reader::ValueReader;
14+
use cid::Cid;
15+
use fil_actors_runtime::runtime::{ActorCode, Runtime};
16+
use fvm_shared::{MethodNum, METHOD_CONSTRUCTOR};
17+
use num_derive::FromPrimitive;
18+
use num_traits::FromPrimitive;
1319

1420
pub use types::*;
1521

@@ -20,19 +26,6 @@ pub(crate) mod reader;
2026
mod state;
2127
mod types;
2228

23-
use {
24-
crate::interpreter::{execute, Bytecode, ExecutionState, System},
25-
cid::Cid,
26-
fil_actors_runtime::{
27-
runtime::{ActorCode, Runtime},
28-
ActorError,
29-
},
30-
fvm_ipld_encoding::tuple::*,
31-
fvm_shared::{MethodNum, METHOD_CONSTRUCTOR},
32-
num_derive::FromPrimitive,
33-
num_traits::FromPrimitive,
34-
};
35-
3629
pub use state::*;
3730

3831
#[cfg(feature = "fil-actor")]
@@ -465,22 +458,3 @@ impl ActorCode for EvmContractActor {
465458
}
466459
}
467460
}
468-
469-
pub type ResurrectParams = ConstructorParams;
470-
471-
#[derive(Serialize_tuple, Deserialize_tuple)]
472-
pub struct DelegateCallParams {
473-
pub code: Cid,
474-
/// The contract invocation parameters
475-
#[serde(with = "strict_bytes")]
476-
pub input: Vec<u8>,
477-
/// The original caller's Eth address.
478-
pub caller: EthAddress,
479-
/// The value passed in the original call.
480-
pub value: TokenAmount,
481-
}
482-
483-
#[derive(Serialize_tuple, Deserialize_tuple)]
484-
pub struct GetStorageAtParams {
485-
pub storage_key: U256,
486-
}

actors/evm/src/state.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ use std::array::TryFromSliceError;
33
use fil_actors_evm_shared::uints::U256;
44
use fvm_shared::ActorID;
55

6-
use {
7-
cid::Cid,
8-
fvm_ipld_encoding::strict_bytes,
9-
fvm_ipld_encoding::tuple::*,
10-
serde::{Deserialize, Serialize},
11-
serde_tuple::{Deserialize_tuple, Serialize_tuple},
12-
};
6+
use cid::Cid;
7+
use fvm_ipld_encoding::strict_bytes;
8+
use fvm_ipld_encoding::tuple::*;
9+
use serde::{Deserialize, Serialize};
10+
use serde_tuple::{Deserialize_tuple, Serialize_tuple};
1311

1412
/// A tombstone indicating that the contract has been self-destructed.
1513
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize_tuple, Deserialize_tuple)]
@@ -137,6 +135,7 @@ mod test {
137135
use fvm_ipld_encoding::{from_slice, to_vec, BytesDe};
138136

139137
use crate::BytecodeHash;
138+
140139
#[test]
141140
fn test_bytecode_hash_serde() {
142141
let encoded = to_vec(&BytecodeHash::EMPTY).unwrap();

actors/evm/src/types.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use cid::Cid;
12
use fil_actors_evm_shared::address::EthAddress;
3+
use fil_actors_evm_shared::uints::U256;
4+
use fvm_ipld_encoding::strict_bytes;
25
use fvm_ipld_encoding::tuple::*;
36
use fvm_ipld_encoding::RawBytes;
7+
use fvm_shared::econ::TokenAmount;
48

59
#[derive(Serialize_tuple, Deserialize_tuple)]
610
pub struct ConstructorParams {
@@ -9,3 +13,22 @@ pub struct ConstructorParams {
913
/// The initcode that will construct the new EVM actor.
1014
pub initcode: RawBytes,
1115
}
16+
17+
pub type ResurrectParams = ConstructorParams;
18+
19+
#[derive(Serialize_tuple, Deserialize_tuple)]
20+
pub struct DelegateCallParams {
21+
pub code: Cid,
22+
/// The contract invocation parameters
23+
#[serde(with = "strict_bytes")]
24+
pub input: Vec<u8>,
25+
/// The original caller's Eth address.
26+
pub caller: EthAddress,
27+
/// The value passed in the original call.
28+
pub value: TokenAmount,
29+
}
30+
31+
#[derive(Serialize_tuple, Deserialize_tuple)]
32+
pub struct GetStorageAtParams {
33+
pub storage_key: U256,
34+
}

actors/market/src/lib.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use fil_actors_runtime::{
3737
};
3838
use fvm_ipld_encoding::ipld_block::IpldBlock;
3939
use fvm_ipld_encoding::{RawBytes, DAG_CBOR};
40+
use fvm_shared::sys::SendFlags;
4041

4142
use crate::ext::verifreg::{AllocationID, AllocationRequest};
4243

@@ -234,14 +235,31 @@ impl Actor {
234235
));
235236
}
236237

238+
// Deals that passed `AuthenticateMessage` and other state-less checks.
239+
let mut validity_index: Vec<bool> = Vec::with_capacity(params.deals.len());
240+
237241
let baseline_power = request_current_baseline_power(rt)?;
238242
let (network_raw_power, _) = request_current_network_power(rt)?;
239243

244+
// We perform these checks before loading state since the call to `AuthenticateMessage` could recurse
245+
for (di, deal) in params.deals.iter().enumerate() {
246+
let valid = if let Err(e) = validate_deal(rt, deal, &network_raw_power, &baseline_power)
247+
{
248+
info!("invalid deal {}: {}", di, e);
249+
false
250+
} else {
251+
true
252+
};
253+
254+
validity_index.push(valid);
255+
}
256+
240257
struct ValidDeal {
241258
proposal: DealProposal,
242259
serialized_proposal: RawBytes,
243260
cid: Cid,
244261
}
262+
245263
// Deals that passed validation.
246264
let mut valid_deals: Vec<ValidDeal> = Vec::with_capacity(params.deals.len());
247265
// CIDs of valid proposals.
@@ -260,8 +278,10 @@ impl Actor {
260278
let state: State = rt.state()?;
261279

262280
for (di, mut deal) in params.deals.into_iter().enumerate() {
263-
if let Err(e) = validate_deal(rt, &deal, &network_raw_power, &baseline_power) {
264-
info!("invalid deal {}: {}", di, e);
281+
if !*validity_index.get(di).context_code(
282+
ExitCode::USR_ASSERTION_FAILED,
283+
"validity index has incorrect length",
284+
)? {
265285
continue;
266286
}
267287

@@ -355,7 +375,7 @@ impl Actor {
355375
client_alloc_reqs
356376
.entry(client_id)
357377
.or_default()
358-
.push((pcid, alloc_request_for_deal(&deal, rt.policy(), curr_epoch)));
378+
.push((pcid, alloc_request_for_deal(&deal.proposal, rt.policy(), curr_epoch)));
359379
}
360380

361381
total_provider_lockup = provider_lockup;
@@ -444,7 +464,9 @@ impl Actor {
444464
Ok(())
445465
})?;
446466

447-
// notify clients ignoring any errors
467+
// notify clients, any failures cause the entire publish_storage_deals method to fail
468+
// it's unsafe to ignore errors here, since that could be used to attack storage contract clients
469+
// that might be unaware they're making storage deals
448470
for (i, valid_deal) in valid_deals.iter().enumerate() {
449471
_ = extract_send_result(rt.send_simple(
450472
&valid_deal.proposal.client,
@@ -454,7 +476,10 @@ impl Actor {
454476
deal_id: new_deal_ids[i],
455477
})?,
456478
TokenAmount::zero(),
457-
));
479+
))
480+
.with_context_code(ExitCode::USR_ILLEGAL_ARGUMENT, || {
481+
format!("failed to notify deal with proposal cid {}", valid_deal.cid)
482+
})?;
458483
}
459484

460485
Ok(PublishStorageDealsReturn { ids: new_deal_ids, valid_deals: valid_input_bf })
@@ -1083,21 +1108,21 @@ pub fn validate_and_return_deal_space<BS: Blockstore>(
10831108

10841109
fn alloc_request_for_deal(
10851110
// Deal proposal must have ID addresses
1086-
deal: &ClientDealProposal,
1111+
deal: &DealProposal,
10871112
policy: &Policy,
10881113
curr_epoch: ChainEpoch,
10891114
) -> ext::verifreg::AllocationRequest {
1090-
let alloc_term_min = deal.proposal.end_epoch - deal.proposal.start_epoch;
1115+
let alloc_term_min = deal.end_epoch - deal.start_epoch;
10911116
let alloc_term_max = min(
10921117
alloc_term_min + policy.market_default_allocation_term_buffer,
10931118
policy.maximum_verified_allocation_term,
10941119
);
10951120
let alloc_expiration =
1096-
min(deal.proposal.start_epoch, curr_epoch + policy.maximum_verified_allocation_expiration);
1121+
min(deal.start_epoch, curr_epoch + policy.maximum_verified_allocation_expiration);
10971122
ext::verifreg::AllocationRequest {
1098-
provider: deal.proposal.provider.id().unwrap(),
1099-
data: deal.proposal.piece_cid,
1100-
size: deal.proposal.piece_size,
1123+
provider: deal.provider.id().unwrap(),
1124+
data: deal.piece_cid,
1125+
size: deal.piece_size,
11011126
term_min: alloc_term_min,
11021127
term_max: alloc_term_max,
11031128
expiration: alloc_expiration,
@@ -1293,14 +1318,16 @@ fn deal_proposal_is_internally_valid(
12931318
// Generate unsigned bytes
12941319
let proposal_bytes = serialize(&proposal.proposal, "deal proposal")?;
12951320

1296-
extract_send_result(rt.send_simple(
1321+
extract_send_result(rt.send(
12971322
&proposal.proposal.client,
12981323
ext::account::AUTHENTICATE_MESSAGE_METHOD,
12991324
IpldBlock::serialize_cbor(&ext::account::AuthenticateMessageParams {
13001325
signature: signature_bytes,
13011326
message: proposal_bytes.to_vec(),
13021327
})?,
13031328
TokenAmount::zero(),
1329+
None,
1330+
SendFlags::READ_ONLY,
13041331
))
13051332
.map_err(|e| e.wrap("proposal authentication failed"))?;
13061333
Ok(())

actors/market/tests/cron_tick_timedout_deals.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use fvm_shared::METHOD_SEND;
1616

1717
use fil_actor_market::ext::account::{AuthenticateMessageParams, AUTHENTICATE_MESSAGE_METHOD};
1818
use fvm_ipld_encoding::ipld_block::IpldBlock;
19+
use fvm_shared::sys::SendFlags;
1920
use num_traits::Zero;
2021

2122
mod harness;
@@ -95,13 +96,16 @@ fn publishing_timed_out_deal_again_should_work_after_cron_tick_as_it_should_no_l
9596
})
9697
.unwrap();
9798

98-
rt.expect_send_simple(
99+
rt.expect_send(
99100
deal_proposal2.client,
100101
AUTHENTICATE_MESSAGE_METHOD,
101102
auth_param,
102103
TokenAmount::zero(),
103104
None,
105+
SendFlags::READ_ONLY,
106+
None,
104107
ExitCode::OK,
108+
None,
105109
);
106110

107111
expect_abort(

0 commit comments

Comments
 (0)