Skip to content

Commit

Permalink
tweak: Verify the pre-allocated address safety of scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
dhedey committed Aug 21, 2024
1 parent db96c6d commit d7f8eed
Show file tree
Hide file tree
Showing 20 changed files with 62 additions and 8 deletions.
2 changes: 1 addition & 1 deletion radix-common/src/types/entity_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl EntityType {
matches!(self, EntityType::GlobalNonFungibleResourceManager)
}

pub const fn is_global_virtual(&self) -> bool {
pub const fn is_global_preallocated(&self) -> bool {
match self {
EntityType::GlobalPreallocatedSecp256k1Account
| EntityType::GlobalPreallocatedEd25519Account
Expand Down
4 changes: 2 additions & 2 deletions radix-common/src/types/node_and_substate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ impl NodeId {
matches!(self.entity_type(), Some(t) if t.is_global_non_fungible_resource_manager())
}

pub const fn is_global_virtual(&self) -> bool {
matches!(self.entity_type(), Some(t) if t.is_global_virtual())
pub const fn is_global_preallocated(&self) -> bool {
matches!(self.entity_type(), Some(t) if t.is_global_preallocated())
}

pub const fn is_internal_kv_store(&self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion radix-engine/src/system/system_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ impl<C: SystemCallbackObject> System<C, Executable> {
continue;
}

if node_id.is_global_virtual() {
if node_id.is_global_preallocated() {
// Allow global virtual and add reference
global_addresses.insert(GlobalAddress::new_or_panic(node_id.clone().into()));
continue;
Expand Down
4 changes: 2 additions & 2 deletions radix-transaction-scenarios/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::internal_prelude::ScenarioCore;
///
/// # Warning
///
/// Any scenario that is run after genesis can not use virtual accounts as users could find private
/// key we're using (these are public private key anyway and we're not trying to hide them) and
/// Any scenario that is run after genesis can not use virtual accounts as users could find the private
/// key we're using (these are public and we're not trying to hide them) and
/// change the account's settings or perhaps even the access rule of the account leading scenarios
/// to fail. An allocated account **MUST** be used for any scenario that runs after genesis.
pub struct PreallocatedAccount {
Expand Down
35 changes: 33 additions & 2 deletions radix-transaction-scenarios/src/runners/dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ mod test {

self.scenario_folder
.put_file("scenario_summary.txt", summary);
self.scenario_folder.verify_no_extra_content_exists()
}
}

Expand Down Expand Up @@ -480,10 +479,12 @@ mod test {
ScenarioFilter::SpecificScenariosByName(btreeset!(
scenario_logical_name.to_string()
)),
&mut ScenarioDumpingHooks::new(scenario_folder),
&mut ScenarioDumpingHooks::new(scenario_folder.clone()),
&mut (),
&VmModules::default(),
);

scenario_folder.verify_no_extra_content_exists();
}
}
}
Expand Down Expand Up @@ -519,6 +520,36 @@ mod test {
metadata.logical_name
);
}

fn on_scenario_ended(&mut self, event: OnScenarioEnded<S>) {
let OnScenarioEnded {
metadata,
end_state,
..
} = event;
if let Some(testnet_run_at) = metadata.testnet_run_at {
if testnet_run_at > ProtocolVersion::EARLIEST {
assert!(
metadata.safe_to_run_on_used_ledger,
"Scenario \"{}\" is set to run on non-Babylon testnets, but is not marked as `safe_to_run_on_used_ledger`. This could break stokenet. Change the scenario to not use pre-allocated addresses, and set `safe_to_run_on_used_ledger` to `true`.",
metadata.logical_name
);
}
}
if metadata.safe_to_run_on_used_ledger {
for (address_name, address) in end_state.output.interesting_addresses.0.iter() {
if let DescribedAddress::Global(address) = address {
let entity_type = address.as_node_id().entity_type().unwrap();
assert!(
!entity_type.is_global_preallocated(),
"Scenario \"{}\" is marked as `safe_to_run_on_used_ledger`, but its interesting address {} is pre-allocated - which suggests the scenario can be broken by someone messing with this address before the scenario runs. Change the scenario to explicitly create accounts/identities (see e.g. `maya-router.rs`).",
metadata.logical_name,
address_name,
);
}
}
}
}
}
TransactionScenarioExecutor::new(
InMemorySubstateDatabase::standard(),
Expand Down
9 changes: 9 additions & 0 deletions radix-transaction-scenarios/src/scenario.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,15 @@ pub struct ScenarioMetadata {
/// Note that setting this will change the definition of the given protocol update,
/// so shouldn't be changed once the protocol update is locked in.
pub testnet_run_at: Option<ProtocolVersion>,
/// This setting should be `true` for new scenarios, because new scenarios should
/// not use pre-allocated account addresses which may already exist on-ledger,
/// which could break scenario execution.
///
/// A test validates adherence to this:
/// * If `!safe_to_run_on_used_ledger` then `testnet_run_at` is not past genesis.
/// * If `safe_to_run_on_used_ledger` then pre-allocated account/identity addresses
/// do not appear in well-known addresses.
pub safe_to_run_on_used_ledger: bool,
}

pub trait ScenarioCreator: Sized + 'static + Send + Sync {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl ScenarioCreator for AccessControllerV2ScenarioCreator {
logical_name: "access-controller-v2",
protocol_min_requirement: ProtocolVersion::Bottlenose,
testnet_run_at: Some(ProtocolVersion::Bottlenose),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl ScenarioCreator for AccountAuthorizedDepositorsScenarioCreator {
logical_name: "account_authorized_depositors",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl ScenarioCreator for AccountLockerScenarioCreator {
logical_name: "account_locker",
protocol_min_requirement: ProtocolVersion::Bottlenose,
testnet_run_at: Some(ProtocolVersion::Bottlenose),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl ScenarioCreator for FungibleResourceScenarioCreator {
logical_name: "fungible_resource",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl ScenarioCreator for GlobalNOwnedScenarioCreator {
logical_name: "global_n_owned",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl ScenarioCreator for KVStoreScenarioCreator {
logical_name: "kv_store_with_remote_type",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl ScenarioCreator for MaxTransactionScenarioCreator {
logical_name: "max_transaction",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
1 change: 1 addition & 0 deletions radix-transaction-scenarios/src/scenarios/maya_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl ScenarioCreator for MayaRouterScenarioCreator {
logical_name: "maya_router",
protocol_min_requirement: ProtocolVersion::Bottlenose,
testnet_run_at: Some(ProtocolVersion::Bottlenose),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
1 change: 1 addition & 0 deletions radix-transaction-scenarios/src/scenarios/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl ScenarioCreator for MetadataScenarioCreator {
logical_name: "metadata",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl ScenarioCreator for NonFungibleResourceScenarioCreator {
logical_name: "non_fungible_resource",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl ScenarioCreator for NonFungibleResourceWithRemoteTypeScenarioCreator {
logical_name: "non_fungible_resource_with_remote_type",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
1 change: 1 addition & 0 deletions radix-transaction-scenarios/src/scenarios/radiswap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl ScenarioCreator for RadiswapScenarioCreator {
logical_name: "radiswap",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down
1 change: 1 addition & 0 deletions radix-transaction-scenarios/src/scenarios/royalties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl ScenarioCreator for RoyaltiesScenarioCreator {
logical_name: "royalties",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: true,
};

fn create_with_config_and_state(
Expand Down
1 change: 1 addition & 0 deletions radix-transaction-scenarios/src/scenarios/transfer_xrd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl ScenarioCreator for TransferXrdScenarioCreator {
logical_name: "transfer_xrd",
protocol_min_requirement: ProtocolVersion::Babylon,
testnet_run_at: Some(ProtocolVersion::Babylon),
safe_to_run_on_used_ledger: false,
};

fn create_with_config_and_state(
Expand Down

0 comments on commit d7f8eed

Please sign in to comment.