diff --git a/Cargo.lock b/Cargo.lock index 8401b18b6c..3ffac6a501 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4659,11 +4659,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if 1.0.0", "foreign-types", "libc", @@ -4691,18 +4691,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.27.0+1.1.1v" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", diff --git a/Makefile b/Makefile index 448a34f08f..dd8a955d5f 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ lint-smart-contracts: .PHONY: audit-rs audit-rs: - $(CARGO) audit --ignore RUSTSEC-2024-0332 --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0348 --ignore RUSTSEC-2024-0349 --ignore RUSTSEC-2024-0351 --ignore RUSTSEC-2024-0350 --ignore RUSTSEC-2024-0352 --ignore RUSTSEC-2024-0353 + $(CARGO) audit --ignore RUSTSEC-2024-0357 --ignore RUSTSEC-2023-0045 --ignore RUSTSEC-2024-0332 --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0348 --ignore RUSTSEC-2024-0349 --ignore RUSTSEC-2024-0351 --ignore RUSTSEC-2024-0350 --ignore RUSTSEC-2024-0352 --ignore RUSTSEC-2024-0353 .PHONY: audit-as audit-as: diff --git a/binary_port/src/error_code.rs b/binary_port/src/error_code.rs index e6657ec756..4b0e7b794d 100644 --- a/binary_port/src/error_code.rs +++ b/binary_port/src/error_code.rs @@ -274,6 +274,9 @@ pub enum ErrorCode { /// Gas price tolerance too low #[error("gas price tolerance too low")] GasPriceToleranceTooLow = 85, + /// Received V1 Transaction for spec exec. + #[error("received v1 transaction for speculative execution")] + ReceivedV1Transaction = 86, } impl TryFrom for ErrorCode { @@ -367,6 +370,7 @@ impl TryFrom for ErrorCode { 83 => Ok(ErrorCode::InvalidTransactionEntryPointCannotBeCall), 84 => Ok(ErrorCode::InvalidTransactionInvalidTransactionKind), 85 => Ok(ErrorCode::GasPriceToleranceTooLow), + 86 => Ok(ErrorCode::ReceivedV1Transaction), _ => Err(UnknownErrorCode), } } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 038f7535c5..1f11b8137a 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -1344,6 +1344,19 @@ where self } + /// Expect failure of the protocol upgrade. + pub fn expect_upgrade_failure(&mut self) -> &mut Self { + // Check first result, as only first result is interesting for a simple test + let result = self + .upgrade_results + .last() + .expect("Expected to be called after a system upgrade."); + + assert!(result.is_err(), "Expected Failure got {:?}", result); + + self + } + /// Returns the "handle payment" contract, panics if it can't be found. pub fn get_handle_payment_contract(&self) -> EntityWithNamedKeys { let hash = self diff --git a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs index 1e4296a99c..de5f92bd4c 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs @@ -707,3 +707,28 @@ fn should_correctly_migrate_and_prune_system_contract_records() { .expect("must have system entity"); } } + +#[test] +fn should_not_migrate_bids_with_invalid_min_max_delegation_amounts() { + let mut builder = LmdbWasmTestBuilder::default(); + + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + + let sem_ver = PROTOCOL_VERSION.value(); + let new_protocol_version = + ProtocolVersion::from_parts(sem_ver.major, sem_ver.minor, sem_ver.patch + 1); + + let mut upgrade_request = { + UpgradeRequestBuilder::new() + .with_current_protocol_version(PROTOCOL_VERSION) + .with_new_protocol_version(new_protocol_version) + .with_activation_point(DEFAULT_ACTIVATION_POINT) + .with_maximum_delegation_amount(250_000_000_000) + .with_minimum_delegation_amount(500_000_000_000) + .build() + }; + + builder + .upgrade(&mut upgrade_request) + .expect_upgrade_failure(); +} diff --git a/node/Cargo.toml b/node/Cargo.toml index a9c27c54fb..b0a8e6883a 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -51,7 +51,7 @@ num-rational = { version = "0.4.0", features = ["serde"] } num-traits = "0.2.10" num_cpus = "1" once_cell = "1" -openssl = "0.10.55" +openssl = "0.10.66" pin-project = "1.0.6" prometheus = "0.12.0" quanta = "0.7.2" diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index 2515f9cfb6..a3c83d7ab0 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -1019,6 +1019,9 @@ where SpeculativeExecutionResult::WasmV1(spec_exec_result) => { BinaryResponse::from_value(spec_exec_result, protocol_version) } + SpeculativeExecutionResult::ReceivedV1Transaction => { + BinaryResponse::new_error(ErrorCode::ReceivedV1Transaction, protocol_version) + } } } diff --git a/node/src/components/consensus/protocols/zug.rs b/node/src/components/consensus/protocols/zug.rs index 1731b448b3..87135cebdb 100644 --- a/node/src/components/consensus/protocols/zug.rs +++ b/node/src/components/consensus/protocols/zug.rs @@ -79,7 +79,7 @@ use datasize::DataSize; use either::Either; use itertools::Itertools; use rand::{seq::IteratorRandom, Rng}; -use tracing::{debug, error, event, info, warn, Level}; +use tracing::{debug, error, event, info, trace, warn, Level}; use casper_types::{Chainspec, TimeDiff, Timestamp, U512}; @@ -424,7 +424,7 @@ impl Zug { if self.evidence_only || self.finalized_switch_block() { return vec![]; // Era has ended. No further progress is expected. } - debug!( + trace!( our_idx = self.our_idx(), instance_id = ?self.instance_id(), "syncing with random peer", diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index b9bc8ddb64..99ebd9c219 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -1248,19 +1248,49 @@ where return SpeculativeExecutionResult::invalid_gas_limit(transaction); } }; - let wasm_v1_result = match WasmV1Request::new_session( - *state_root_hash, - block_time.into(), - gas_limit, - &transaction, - ) { - Ok(wasm_v1_request) => execution_engine_v1.execute(state_provider, wasm_v1_request), - Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), - }; - SpeculativeExecutionResult::WasmV1(utils::spec_exec_from_wasm_v1_result( - wasm_v1_result, - block_header.block_hash(), - )) + + if transaction.is_legacy_transaction() { + if transaction.is_native() { + let limit = Gas::from(chainspec.system_costs_config.mint_costs().transfer); + let protocol_version = chainspec.protocol_version(); + let native_runtime_config = NativeRuntimeConfig::from_chainspec(chainspec); + let transaction_hash = transaction.hash(); + let initiator_addr = transaction.initiator_addr(); + let authorization_keys = transaction.authorization_keys(); + let runtime_args = transaction.session_args().clone(); + + let result = state_provider.transfer(TransferRequest::with_runtime_args( + native_runtime_config.clone(), + *state_root_hash, + protocol_version, + transaction_hash, + initiator_addr, + authorization_keys, + runtime_args, + )); + SpeculativeExecutionResult::WasmV1(utils::spec_exec_from_transfer_result( + limit, + result, + block_header.block_hash(), + )) + } else { + let wasm_v1_result = match WasmV1Request::new_session( + *state_root_hash, + block_time.into(), + gas_limit, + &transaction, + ) { + Ok(wasm_v1_request) => execution_engine_v1.execute(state_provider, wasm_v1_request), + Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), + }; + SpeculativeExecutionResult::WasmV1(utils::spec_exec_from_wasm_v1_result( + wasm_v1_result, + block_header.block_hash(), + )) + } + } else { + SpeculativeExecutionResult::ReceivedV1Transaction + } } #[allow(clippy::too_many_arguments)] diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 8b3f63f572..dd72fe7bbd 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -378,6 +378,7 @@ pub struct BlockAndExecutionArtifacts { pub enum SpeculativeExecutionResult { InvalidTransaction(InvalidTransaction), WasmV1(casper_binary_port::SpeculativeExecutionResult), + ReceivedV1Transaction, } impl SpeculativeExecutionResult { diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 51bf75cc8f..718605be21 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -32,10 +32,13 @@ use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Result}; use casper_storage::{ data_access_layer::{ DataAccessLayer, FlushRequest, FlushResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, + TransferResult, }, global_state::state::{lmdb::LmdbGlobalState, CommitProvider, StateProvider}, }; -use casper_types::{BlockHash, Chainspec, Digest, EraId, GasLimited, Key, ProtocolUpgradeConfig}; +use casper_types::{ + BlockHash, Chainspec, Digest, EraId, Gas, GasLimited, Key, ProtocolUpgradeConfig, +}; /// Maximum number of resource intensive tasks that can be run in parallel. /// @@ -518,6 +521,25 @@ pub(super) fn calculate_prune_eras( Some(range.map(EraId::new).map(Key::EraInfo).collect()) } +pub(crate) fn spec_exec_from_transfer_result( + limit: Gas, + transfer_result: TransferResult, + block_hash: BlockHash, +) -> SpeculativeExecutionResult { + let transfers = transfer_result.transfers().to_owned(); + let consumed = limit; + let effects = transfer_result.effects().to_owned(); + let messages = vec![]; + let error_msg = transfer_result + .error() + .to_owned() + .map(|err| format!("{:?}", err)); + + SpeculativeExecutionResult::new( + block_hash, transfers, limit, consumed, effects, messages, error_msg, + ) +} + pub(crate) fn spec_exec_from_wasm_v1_result( wasm_v1_result: WasmV1Result, block_hash: BlockHash, diff --git a/storage/src/data_access_layer/mint.rs b/storage/src/data_access_layer/mint.rs index 6a2b89a89b..08710925b9 100644 --- a/storage/src/data_access_layer/mint.rs +++ b/storage/src/data_access_layer/mint.rs @@ -156,4 +156,19 @@ impl TransferResult { TransferResult::Success { effects, .. } => effects.clone(), } } + + pub fn transfers(&self) -> Vec { + match self { + TransferResult::RootNotFound | TransferResult::Failure(_) => vec![], + TransferResult::Success { transfers, .. } => transfers.clone(), + } + } + + pub fn error(&self) -> Option { + if let Self::Failure(error) = self { + Some(error.clone()) + } else { + None + } + } } diff --git a/storage/src/system/protocol_upgrade.rs b/storage/src/system/protocol_upgrade.rs index 2ca6f2de6c..fc74da7477 100644 --- a/storage/src/system/protocol_upgrade.rs +++ b/storage/src/system/protocol_upgrade.rs @@ -187,8 +187,8 @@ where self.handle_legacy_accounts_migration()?; self.handle_legacy_contracts_migration()?; self.handle_bids_migration( - self.config.maximum_delegation_amount(), self.config.minimum_delegation_amount(), + self.config.maximum_delegation_amount(), )?; self.handle_era_info_migration() } @@ -950,6 +950,9 @@ where chainspec_minimum: u64, chainspec_maximum: u64, ) -> Result<(), ProtocolUpgradeError> { + if chainspec_maximum < chainspec_minimum { + return Err(ProtocolUpgradeError::InvalidUpgradeConfig); + } debug!("handle bids migration"); let mut tc = self.tracking_copy.borrow_mut(); let existing_bid_keys = match tc.get_keys(&KeyTag::Bid) { diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index 05dc06a1ae..f78ec9bb11 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -661,12 +661,6 @@ where let entity_hash = AddressableEntityHash::new(contract_hash.value()); let entity_key = Key::contract_entity_key(entity_hash); self.write(entity_key, StoredValue::AddressableEntity(updated_entity)); - - // Prune the legacy records. - // Prune the legacy contract. - self.prune(Key::Hash(contract_hash.value())); - // Prune the legacy Wasm record. - self.prune(Key::Hash(contract_wasm_hash.value())); } let access_key_value = CLValue::from_t(access_uref).map_err(Self::Error::CLValue)?; diff --git a/types/Cargo.toml b/types/Cargo.toml index d81202ca22..5a684732fe 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -43,7 +43,7 @@ serde = { version = "1", default-features = false, features = ["alloc", "derive" serde_bytes = { version = "0.11.5", default-features = false, features = ["alloc"] } serde_json = { version = "1.0.59", default-features = false, features = ["alloc"] } strum = { version = "0.24", features = ["derive"], optional = true } -thiserror = {version = "1", optional = true } +thiserror = { version = "1", optional = true } tracing = { version = "0.1.37", default-features = false } uint = { version = "0.9.0", default-features = false } untrusted = { version = "0.7.1", optional = true } @@ -58,7 +58,7 @@ derp = "0.0.14" getrandom = "0.2.0" humantime = "2" once_cell = "1.5.2" -openssl = "0.10.55" +openssl = "0.10.66" pem = "0.8.1" proptest = "1.0.0" proptest-derive = "0.3.0" diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 25b29d7e90..009f500ba7 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -415,6 +415,14 @@ impl Transaction { } } + /// Is the transaction the legacy deploy variant. + pub fn is_legacy_transaction(&self) -> bool { + match self { + Transaction::Deploy(_) => true, + Transaction::V1(_) => false, + } + } + // This method is not intended to be used by third party crates. #[doc(hidden)] #[cfg(feature = "json-schema")]