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

A new Upgrade transaction to perform network upgrades #707

Merged
merged 45 commits into from
Apr 9, 2024

Conversation

xgreenx
Copy link
Collaborator

@xgreenx xgreenx commented Mar 25, 2024

Related FuelLabs/fuel-core#1753 and FuelLabs/fuel-specs#567

The change adds a new Upgrade transaction that allows upgrading either consensus parameters or state transition function used by the network to produce future blocks.

The purpose of the upgrade is defined by the Upgrade Purpose type:

pub enum UpgradePurpose {
    /// The upgrade is performed to change the consensus parameters.
    ConsensusParameters {
        /// The index of the witness in the [`Witnesses`] field that contains
        /// the serialized consensus parameters.
        witness_index: u16,
        /// The hash of the serialized consensus parameters.
        /// Since the serialized consensus parameters live inside witnesses(malleable
        /// data), any party can override them. The `checksum` is used to verify that the
        /// data was not modified.
        checksum: Bytes32,
    },
    /// The upgrade is performed to change the state transition function.
    StateTransition {
        /// The hash of the new bytecode of the state transition function.
        /// The bytecode must be present on the blockchain(should be known by the
        /// network) at the moment of inclusion of this transaction.
        bytecode_hash: Bytes32,
    },
}

The Upgrade transaction is chargeable, and the sender should pay for it. Transaction inputs should contain only base assets.

Only the privileged address can upgrade the network. The privileged address can be either a real account or a predicate.

Since serialized consensus parameters are small(< 2kb), they can be part of the upgrade transaction and live inside of witness data. The bytecode of the blockchain state transition function is huge ~1.6MB(relative to consensus parameters), and it is impossible to fit it into one transaction. So when we perform the upgrade of the state transition function, it should already be available on the blockchain. The transaction to actually upload the bytecode(Upload transaction) will implemented in the FuelLabs/fuel-core#1754.

Side changes:

  • Moved fuel-tx-test-helpers logic into the fuel_tx::test_helpers module.

  • The combination of serde and postcard is used to serialize and deserialize ConsensusParameters during the upgrade. This means the protocol and state transition function requires the serde feature by default for ConsensusParameters and fuel-types.

  • Added a new rule for Create transaction: all inputs should use base asset otherwise it returns TransactionInputContainsNonBaseAssetId error.

  • Renamed some errors because now they are used for several transactions(Upgrade uses some errors from Create and some from Script transactions):

    • TransactionScriptOutputContractCreated -> TransactionOutputContainsContractCreated.
    • TransactionCreateOutputContract -> TransactionOutputContainsContract.
    • TransactionCreateOutputVariable -> TransactionOutputContainsVariable.
    • TransactionCreateOutputChangeNotBaseAsset -> TransactionChangeChangeUsesNotBaseAsset.
    • TransactionCreateInputContract -> TransactionInputContainsContract.
    • TransactionCreateMessageData -> TransactionInputContainsMessageData.
  • Used the same pattern everywhere:

                 Self::Script(tx) => tx.encode_static(buffer),
                 Self::Create(tx) => tx.encode_static(buffer),
                 Self::Mint(tx) => tx.encode_static(buffer),
                 Self::Upgrade(tx) => tx.encode_static(buffer),

    Instead of:

                 Transaction::Script(script) => script.encode_static(buffer),
                 Transaction::Create(create) => create.encode_static(buffer),
                 Transaction::Mint(mint) => mint.encode_static(buffer),
                 Transaction::Upgrade(upgrade) => upgrade.encode_static(buffer),

xgreenx and others added 23 commits March 21, 2024 07:37
Reduced default `MAX_SIZE` to be 110kb.
Reduced default `MAX_CONTRACT_SIZE` to be 100kb.
# Conflicts:
#	CHANGELOG.md
#	fuel-tx/src/builder.rs
#	fuel-tx/src/tests/valid_cases/transaction.rs
#	fuel-tx/src/transaction/consensus_parameters.rs
#	fuel-vm/src/checked_transaction.rs
#	fuel-vm/src/tests/limits.rs
#	fuel-vm/src/tests/validation.rs
…ction

# Conflicts:
#	fuel-tx/src/transaction/consensus_parameters.rs
@xgreenx xgreenx added the no changelog Skips the CI changelog check label Mar 25, 2024
@xgreenx xgreenx requested a review from a team March 25, 2024 13:24
@xgreenx xgreenx self-assigned this Mar 25, 2024
@xgreenx xgreenx changed the title A new Upgrade transaction to perform network upgrades A new Upgrade transaction to perform network upgrades Mar 25, 2024
@xgreenx xgreenx removed the no changelog Skips the CI changelog check label Apr 3, 2024
@xgreenx xgreenx marked this pull request as ready for review April 3, 2024 10:14
Comment on lines +225 to +228
let serialized_consensus_parameters = postcard::to_allocvec(consensus_parameters)
.map_err(|_| {
ValidityError::TransactionUpgradeConsensusParametersSerialization
})?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm pretty sure this is never supposed to fail

Dentosal
Dentosal previously approved these changes Apr 5, 2024
@xgreenx xgreenx requested review from Dentosal and a team April 7, 2024 07:52
@xgreenx xgreenx added the breaking A breaking api change label Apr 8, 2024
Dentosal
Dentosal previously approved these changes Apr 8, 2024
fuel-tx/src/tests/bytes.rs Show resolved Hide resolved
fuel-tx/src/tests/display.rs Show resolved Hide resolved
fuel-tx/src/tests/offset.rs Show resolved Hide resolved
fuel-tx/src/tests/valid_cases/transaction/upgrade.rs Outdated Show resolved Hide resolved
fuel-tx/src/tests/valid_cases/transaction/upgrade.rs Outdated Show resolved Hide resolved
fuel-tx/src/transaction/id.rs Show resolved Hide resolved
fuel-tx/src/transaction/types/upgrade.rs Show resolved Hide resolved
fuel-vm/src/tests/encoding.rs Show resolved Hide resolved
xgreenx added a commit to FuelLabs/fuel-specs that referenced this pull request Apr 9, 2024
Corresponding implementation:
FuelLabs/fuel-vm#707

The change adds a new `Upgrade` transaction that allows upgrading either
consensus parameters or state transition function used by the network to
produce future blocks.

The purpose of the upgrade is defined by the `Upgrade Purpose` type.

The `Upgrade` transaction is chargeable, and the sender should pay for
it. Transaction inputs should contain only base assets.

Only the privileged address can upgrade the network. The privileged
address can be either a real account or a predicate.

We use postcard algorithm to serialize and deserialize consensus
parameters during the upgrade. This algorithm works with numbers in a
more sufficient way and compresses them well.
@xgreenx xgreenx added this pull request to the merge queue Apr 9, 2024
Merged via the queue into master with commit 2ee9c12 Apr 9, 2024
38 checks passed
@xgreenx xgreenx deleted the feature/upgrade-transaction branch April 9, 2024 19:22
@xgreenx xgreenx mentioned this pull request Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking A breaking api change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants