Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle new state transition bytecode and new consensus parameter version #2621

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2dd8965
tests: Initial test suite for merklized storage updates
netrome Jan 17, 2025
ce34251
chore: Add changelog
netrome Jan 17, 2025
06c9de2
chore: Deny warnings
netrome Jan 28, 2025
626cb5f
Store state transition bytecode version and consensus parameter versi…
acerone85 Jan 22, 2025
5c6976f
Remove dependency from IterableStore
acerone85 Jan 22, 2025
1c84bf8
Remove todo
acerone85 Jan 22, 2025
57db1ca
Add helper trait to retrieve latest consensus parameters and state tr…
acerone85 Jan 23, 2025
1db781e
Avoid recomputing metadata
acerone85 Jan 23, 2025
4e39edd
Implement IterableStore for DummyStorage
acerone85 Jan 23, 2025
7fab0c1
Update crates/fraud_proofs/global_merkle_root/storage/src/update.rs
acerone85 Jan 28, 2025
453819e
Remove unused ReadTransaction
acerone85 Jan 28, 2025
c8e6774
Remove IterableStore trait bound for
acerone85 Jan 28, 2025
05442ce
tests: Initial test suite for merklized storage updates
netrome Jan 17, 2025
a370f4f
chore: Add changelog
netrome Jan 17, 2025
b9bdd5e
chore: Deny warnings
netrome Jan 28, 2025
7382104
refactor: Rename update_tx -> storage_update_tx
netrome Jan 30, 2025
92b1d22
chore: Add explanatory comments
netrome Jan 30, 2025
5a7ccd1
fix: Return storage in `update_merklized_tables`
netrome Jan 30, 2025
06dd547
fix: Rename `merklized` -> `merkleized`
netrome Jan 30, 2025
1fa8a92
refactor: More informative name for test helper trait
netrome Jan 30, 2025
80bd2b6
refactor: Rename `update_tx` to `storage_update_tx` in one more test
netrome Jan 30, 2025
c79a153
refactor: Take a mutable self receiver in UpdateMerkleizedTables trait
netrome Jan 30, 2025
e22205f
Store state transition bytecode version and consensus parameter versi…
acerone85 Jan 22, 2025
fdba665
Remove dependency from IterableStore
acerone85 Jan 22, 2025
e171887
Remove todo
acerone85 Jan 22, 2025
89b2d2e
Add helper trait to retrieve latest consensus parameters and state tr…
acerone85 Jan 23, 2025
71bf996
Avoid recomputing metadata
acerone85 Jan 23, 2025
07de424
Implement IterableStore for DummyStorage
acerone85 Jan 23, 2025
d37eb0e
Update crates/fraud_proofs/global_merkle_root/storage/src/update.rs
acerone85 Jan 28, 2025
5379df8
Remove unused ReadTransaction
acerone85 Jan 28, 2025
538e66b
Remove IterableStore trait bound for
acerone85 Jan 28, 2025
69528e2
Implement IterableStore for InMemoryStorage
acerone85 Jan 29, 2025
9e80511
Tests for upgrade transaction
acerone85 Jan 29, 2025
16593b7
Minor improvements
acerone85 Jan 30, 2025
2b71419
Changelog
acerone85 Jan 30, 2025
09b3f1f
Fix Cargo.toml formatting issue
acerone85 Jan 30, 2025
f519225
Placate Clippy
acerone85 Jan 30, 2025
a36f417
Fix compilation
acerone85 Jan 30, 2025
c61ec39
Merge remote-tracking branch 'origin/2584-fault_provingglobal_roots-p…
xgreenx Jan 31, 2025
9f9f383
Removed iterator and use versions from the header
xgreenx Jan 31, 2025
8737fe6
Calculate metadata if it is not avaialble
xgreenx Jan 31, 2025
87e179a
Merge branch 'master' into 2584-fault_provingglobal_roots-populate-ta…
acerone85 Feb 3, 2025
ca06a26
Small inconsistencies after git merge master
acerone85 Feb 3, 2025
7b1e6d3
Merge remote-tracking branch 'origin/master' into 2584-fault_provingg…
acerone85 Feb 4, 2025
447de60
Update crates/fraud_proofs/global_merkle_root/storage/src/update.rs
acerone85 Feb 4, 2025
9e38374
Fmt
acerone85 Feb 4, 2025
735062d
Merge remote-tracking branch 'origin/master' into 2584-fault_provingg…
acerone85 Feb 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added
- [2668](https://github.com/FuelLabs/fuel-core/pull/2668): Expose gas price service test helpers
- [2621](https://github.com/FuelLabs/fuel-core/pull/2598): Global merkle root storage updates process upgrade transactions.

## [Version 0.41.5]

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion crates/fraud_proofs/global_merkle_root/storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ strum = { workspace = true }
strum_macros = { workspace = true }

[dev-dependencies]
fuel-core-storage = { workspace = true, default-features = false, features = [
fuel-core-storage = { workspace = true, features = ["alloc", "test-helpers"] }
fuel-core-types = { workspace = true, features = [
"serde",
"alloc",
"test-helpers",
] }
postcard = { workspace = true, features = ["alloc"] }
rand = { workspace = true }

[features]
Expand Down
196 changes: 190 additions & 6 deletions crates/fraud_proofs/global_merkle_root/storage/src/update.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::{
column::Column,
Coins,
ConsensusParametersVersions,
ContractsLatestUtxo,
Messages,
StateTransitionBytecodeVersions,
};
use alloc::{
borrow::Cow,
Expand All @@ -15,7 +17,13 @@ use fuel_core_storage::{
StorageAsMut,
};
use fuel_core_types::{
blockchain::block::Block,
blockchain::{
block::Block,
header::{
ConsensusParametersVersion,
StateTransitionBytecodeVersion,
},
},
entities::{
coins::coin::CompressedCoinV1,
contract::ContractUtxoInfo,
Expand All @@ -27,6 +35,7 @@ use fuel_core_types::{
Inputs,
OutputContract,
Outputs,
UpgradePurpose as _,
},
input::{
self,
Expand All @@ -51,6 +60,9 @@ use fuel_core_types::{
Transaction,
TxPointer,
UniqueIdentifier,
Upgrade,
UpgradeMetadata,
UpgradePurpose,
UtxoId,
},
fuel_types::{
Expand Down Expand Up @@ -83,6 +95,12 @@ where
let mut update_transaction = UpdateMerkleizedTablesTransaction {
chain_id,
storage: self,
latest_state_transition_bytecode_version: block
.header()
.state_transition_bytecode_version,
latest_consensus_parameters_version: block
.header()
.consensus_parameters_version,
};

update_transaction.process_block(block)?;
Expand All @@ -94,6 +112,8 @@ where
struct UpdateMerkleizedTablesTransaction<'a, Storage> {
chain_id: ChainId,
storage: &'a mut StorageTransaction<Storage>,
latest_consensus_parameters_version: ConsensusParametersVersion,
latest_state_transition_bytecode_version: StateTransitionBytecodeVersion,
}

impl<'a, Storage> UpdateMerkleizedTablesTransaction<'a, Storage>
Expand Down Expand Up @@ -134,8 +154,10 @@ where
self.process_output(tx_pointer, utxo_id, &inputs, output)?;
}

if let Transaction::Upgrade(tx) = tx {
self.process_upgrade_transaction(tx)?;
}
// TODO(#2583): Add the transaction to the `ProcessedTransactions` table.
// TODO(#2584): Insert state transition bytecode and consensus parameter updates.
// TODO(#2585): Insert uplodade bytecodes.
// TODO(#2586): Insert blobs.
// TODO(#2587): Insert raw code for created contracts.
Expand Down Expand Up @@ -267,6 +289,55 @@ where
}
Ok(())
}

fn process_upgrade_transaction(&mut self, tx: &Upgrade) -> anyhow::Result<()> {
let metadata = match tx.metadata() {
Some(metadata) => metadata.body.clone(),
None => UpgradeMetadata::compute(tx).map_err(|e| anyhow::anyhow!(e))?,
};

match metadata {
UpgradeMetadata::ConsensusParameters {
consensus_parameters,
calculated_checksum: _,
} => {
let Some(next_consensus_parameters_version) =
self.latest_consensus_parameters_version.checked_add(1)
else {
return Err(anyhow::anyhow!("Invalid consensus parameters version"));
};
self.latest_consensus_parameters_version =
next_consensus_parameters_version;
self.storage
.storage::<ConsensusParametersVersions>()
.insert(
&self.latest_consensus_parameters_version,
&consensus_parameters,
)?;
}
UpgradeMetadata::StateTransition => match tx.upgrade_purpose() {
UpgradePurpose::ConsensusParameters { .. } => unreachable!(
"Upgrade with StateTransition metadata should have StateTransition purpose"
),
UpgradePurpose::StateTransition { root } => {
let Some(next_state_transition_bytecode_version) =
self.latest_state_transition_bytecode_version.checked_add(1)
else {
return Err(anyhow::anyhow!(
"Invalid state transition bytecode version"
));
};
self.latest_state_transition_bytecode_version =
next_state_transition_bytecode_version;
self.storage
.storage::<StateTransitionBytecodeVersions>()
.insert(&self.latest_state_transition_bytecode_version, root)?;
}
},
}

Ok(())
}
}

pub trait TransactionInputs {
Expand Down Expand Up @@ -320,10 +391,17 @@ mod tests {
},
StorageAsRef,
};
use fuel_core_types::fuel_tx::{
Bytes32,
ContractId,
TxId,
use fuel_core_types::{
fuel_crypto::Hasher,
fuel_tx::{
Bytes32,
ConsensusParameters,
ContractId,
Finalizable,
TransactionBuilder,
TxId,
Witness,
},
};

use rand::{
Expand Down Expand Up @@ -528,6 +606,92 @@ mod tests {
assert!(coin_doesnt_exist_after_process_input);
}

#[test]
fn process_upgrade_transaction_should_update_latest_state_transition_bytecode_version_when_interacting_with_relevant_upgrade(
) {
// Given
let new_root = Bytes32::from([1; 32]);
let upgrade_tx = TransactionBuilder::upgrade(UpgradePurpose::StateTransition {
root: new_root,
})
.finalize();

let mut storage = InMemoryStorage::default();

// When
let state_transition_bytecode_version_before_upgrade = 1;
let state_transition_bytecode_version_after_upgrade =
state_transition_bytecode_version_before_upgrade + 1;

let mut storage_tx = storage.write_transaction();
let mut update_tx = storage_tx
.construct_update_merkleized_tables_transaction_with_versions(
state_transition_bytecode_version_before_upgrade,
0,
);
update_tx.process_upgrade_transaction(&upgrade_tx).unwrap();

let state_transition_bytecode_root_after_upgrade = storage_tx
.storage_as_ref::<StateTransitionBytecodeVersions>()
.get(&state_transition_bytecode_version_after_upgrade)
.expect("In memory Storage should not return an error")
.expect("State transition bytecode version after upgrade should be present")
.into_owned();

// Then
assert_eq!(state_transition_bytecode_version_before_upgrade, 1);
assert_eq!(state_transition_bytecode_version_after_upgrade, 2);
assert_eq!(state_transition_bytecode_root_after_upgrade, new_root);
}

#[test]
fn process_upgrade_transaction_should_update_latest_consensus_parameters_version_when_interacting_with_relevant_upgrade(
) {
// Given
let consensus_parameters = ConsensusParameters::default();
let serialized_consensus_parameters =
postcard::to_allocvec(&consensus_parameters)
.expect("Consensus parameters serialization should succeed");
let tx_witness = Witness::from(serialized_consensus_parameters.clone());
let serialized_witness = tx_witness.as_vec();
let checksum = Hasher::hash(serialized_witness);
let upgrade_tx =
TransactionBuilder::upgrade(UpgradePurpose::ConsensusParameters {
witness_index: 0,
checksum,
})
.add_witness(tx_witness)
.finalize();

let mut storage = InMemoryStorage::default();

// When
let consensus_parameters_version_before_upgrade = 1;
let consensus_parameters_version_after_upgrade =
consensus_parameters_version_before_upgrade + 1;

let mut storage_tx = storage.write_transaction();
let mut update_tx = storage_tx
.construct_update_merkleized_tables_transaction_with_versions(
0,
consensus_parameters_version_before_upgrade,
);

update_tx.process_upgrade_transaction(&upgrade_tx).unwrap();

let consensus_parameters_after_upgrade = storage_tx
.storage_as_ref::<ConsensusParametersVersions>()
.get(&consensus_parameters_version_after_upgrade)
.expect("In memory Storage should not return an error")
.expect("State transition bytecode version after upgrade should be present")
.into_owned();

// Then
assert_eq!(consensus_parameters_version_before_upgrade, 1);
assert_eq!(consensus_parameters_version_after_upgrade, 2);
assert_eq!(consensus_parameters_after_upgrade, consensus_parameters);
}

fn random_utxo_id(rng: &mut impl rand::RngCore) -> UtxoId {
let mut txid = TxId::default();
rng.fill_bytes(txid.as_mut());
Expand Down Expand Up @@ -562,6 +726,12 @@ mod tests {
fn construct_update_merkleized_tables_transaction(
self,
) -> UpdateMerkleizedTablesTransaction<'a, Self::Storage>;

fn construct_update_merkleized_tables_transaction_with_versions(
self,
latest_state_transition_bytecode_version: StateTransitionBytecodeVersion,
latest_consensus_parameters_version: ConsensusParametersVersion,
) -> UpdateMerkleizedTablesTransaction<'a, Self::Storage>;
}

impl<'a, Storage> ConstructUpdateMerkleizedTablesTransactionForTests<'a>
Expand All @@ -575,6 +745,20 @@ mod tests {
UpdateMerkleizedTablesTransaction {
chain_id: ChainId::default(),
storage: self,
latest_consensus_parameters_version: Default::default(),
latest_state_transition_bytecode_version: Default::default(),
}
}
fn construct_update_merkleized_tables_transaction_with_versions(
self,
latest_state_transition_bytecode_version: StateTransitionBytecodeVersion,
latest_consensus_parameters_version: ConsensusParametersVersion,
) -> UpdateMerkleizedTablesTransaction<'a, Self::Storage> {
UpdateMerkleizedTablesTransaction {
chain_id: ChainId::default(),
storage: self,
latest_consensus_parameters_version,
latest_state_transition_bytecode_version,
}
}
}
Expand Down
Loading