Skip to content

feat: Fast upgrades: upgrade payload section in blocks - #11655

Open
frankdavid wants to merge 21 commits into
masterfrom
frankdavid/fast-upgrades-block-payload
Open

frankdavid wants to merge 21 commits into
masterfrom
frankdavid/fast-upgrades-block-payload

Conversation

@frankdavid

Copy link
Copy Markdown
Contributor

Add the upgrade section to block payloads and wire it into the payload builder infrastructure (with a placeholder builder for now).

  • Add upgrade_payload_bytes to the Block proto and upgrade to BatchPayload/BatchMessages
  • Add an Upgrade section to BatchPayloadSectionBuilder
  • Add the ic-consensus-upgrade crate with a placeholder UpgradePayloadBuilder

First step of the Phase-2 rolling-reboot consensus protocol, which adds the data types and the artifact mechanism.

* Add `UpgradePermitAction` (`Request` / `Authorize` / `Return`). `UpgradePermitAuthorizationRequest` is the signed content, `UpgradePermitAuthorizationShare` is the gossiped artifact.
* Add the in-memory `UpgradePermitAuthPoolImpl` which is modeled after other pools.
* Add the `ic-consensus-upgrade` crate with `UpgradePermitAuthPoolManager`. It signs shares for requests in finalized blocks and validates gossiped shares.
* Register the new proto file with the generator and add `UpgradePermitAuthorizationRequest` (signing) and `UpgradePermitAuthorizationShare` (pool-ID hashing) domain separators.
Add the upgrade section to block payloads and wire it into the payload builder infrastructure (with a placeholder builder for now).

- Add `upgrade_payload_bytes` to the `Block` proto and upgrade to `BatchPayload`/`BatchMessages`
- Add an `Upgrade` section to `BatchPayloadSectionBuilder`
- Add the `ic-consensus-upgrade` crate with a placeholder `UpgradePayloadBuilder`
@frankdavid
frankdavid added this pull request to stack #11656 September 22, 2026 20:20
@frankdavid
frankdavid requested a review from a team as a code owner September 22, 2026 20:20
@github-actions github-actions Bot added the feat label Sep 22, 2026
@zeropath-ai

zeropath-ai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

✅ No security or compliance issues detected. Reviewed everything up to 5324358.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► rs/consensus/upgrade/BUILD.bazel
    Add upgrade module to build dependencies
► rs/consensus/upgrade/Cargo.toml
    Add ic-consensus-upgrade dependency
► rs/consensus/upgrade/src/lib.rs
    Introduce upgrade payload builder module
► rs/consensus/upgrade/src/payload_builder.rs
    Implement UpgradePayloadBuilderImpl with build/validate methods
Enhancement ► rs/interfaces/src/upgrade.rs
    Define InvalidUpgradePayloadReason enum
► rs/interfaces/src/consensus.rs
    Add InvalidUpgradePayload to InvalidPayloadReason
Enhancement ► rs/protobuf/def/types/v1/consensus.proto
    Add upgrade_payload_bytes field to Block message
► rs/protobuf/src/gen/types/types.v1.rs
    Update Block proto struct to include upgrade_payload_bytes
Enhancement ► rs/types/types/src/batch.rs
    Add upgrade field to BatchPayload
► rs/types/types/src/consensus.rs
    Include upgrade_payload_bytes in Block conversions
Enhancement ► rs/consensus/src/consensus/payload.rs
    Add Upgrade variant to BatchPayloadSectionBuilder and related handling
► rs/consensus/src/consensus/payload_builder.rs
    Update to include Upgrade payload section in builder pipeline
► rs/consensus/src/consensus.rs
    Extend constructor to accept upgrade_payload_builder and wire through tests
Enhancement ► rs/consensus/src/consensus/payload_builder.rs (existing file changes reflected above)
Enhancement ► rs/consensus/BUILD.bazel (existing) updated to include upgrade in various targets (references across BUILD files)
Enhancement ► rs/replica/setup_ic_network/BUILD.bazel
    Include upgrade in consensus dependencies
► rs/replica/setup_ic_network/Cargo.toml
    Add ic-consensus-upgrade dependency
Enhancement ► rs/replica/setup_ic_network/src/lib.rs
    Import UpgradePayloadBuilderImpl and instantiate in start_consensus
Enhancement ► rs/replica/setup_ic_network/src/lib.rs
    Wire upgrade_payload_builder into start_consensus call sites
Enhancement ► rs/consensus/tests/framework/runner.rs
    Pass upgrade_payload_builder through framework dependencies
Enhancement ► rs/consensus/tests/framework/types.rs
    Add upgrade_payload_builder to ConsensusDependencies
Enhancement ► rs/consensus/tests/payload.rs
    Create upgrade_payload_builder and pass to test setup
► rs/consensus/tests/payload.rs
    Include upgrade in consensus payload tests
Enhancement ► rs/consensus/tests/payload.rs
    Adjust test expectations to account for upgrade payload ordering and size calculations
Enhancement ► rs/consensus/upgrade/BUILD.bazel (new file)
► rs/consensus/upgrade/Cargo.toml (new file)
► rs/consensus/upgrade/src/lib.rs (new file)
► rs/consensus/upgrade/src/payload_builder.rs (new file)
Enhancement ► rs/interfaces/src/upgrade.rs (new) and related interface changes across upgrade-related codepaths

@alin-at-dfinity alin-at-dfinity left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The change overall LGTM, but I'll leave it to Leo or Pierugo to approve, particularly since I'm not sure what the changed hashes in the crypto_hash_stability tests imply.

Comment thread rs/protobuf/def/types/v1/consensus.proto Outdated
Comment thread rs/consensus/Cargo.toml Outdated
Comment thread rs/consensus/src/consensus/payload.rs
Comment thread rs/types/types/src/crypto/hash/tests.rs Outdated
assert_eq!(
hex::encode(hash.get_ref().0.as_slice()),
"764535296841f3db421a928cfadff3460be406d0182da64034eee623a9a97e99",
"c20a87578beb94df369dabfefc30c0d47d170c75d68236aae3b16335c0f21c4a",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@pierugo-dfinity, @eichhorl, is this (and the similar hash changes below) OK? Does it require any other changes / staged rollout / whatever?

The comment on mod crypto_hash_stability simply says "hashes [...] must remain constant across code changes".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's a red herring. As Leo mentioned, the better alternative would be to use a summary block for building the CUP instead of a data block here and below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved to summary block

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do you want to split the block and use summary for CUP tests and Data for others (only block_proposal_stability atm)?

@pierugo-dfinity pierugo-dfinity Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it's fine for now (a proposal for a summary block is just as legitimate). If that's not too much of a burden, maybe you could rename fn test_block to fn test_summary_block such that it's clearer for next time (we're already modifying the surrounding code).

logger: ReplicaLogger,
) -> Self {
let section_builder = vec![
BatchPayloadSectionBuilder::Upgrade(upgrade_payload_builder),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why put it first when it is last everywhere else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just for test stability. Otherwise the test would need more changes. The section_builder order should not matter for behavior but if you prefer a particular order, I can change it (and then also change the tests accordingly.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it is cleaner to keep it last here as well, if the plumbing is expected when adding a new section (which is rare) and isn't too demanding.

Comment thread rs/consensus/upgrade/src/payload_builder.rs Outdated
Comment on lines +29 to +36
// TODO: implement proper validation
UpgradePayload::deserialize(payload)
.map(|_| ())
.map_err(|e| {
ValidationError::InvalidArtifact(InvalidPayloadReason::InvalidUpgradePayload(
InvalidUpgradePayloadReason::DecodeFailed(format!("{e:?}")),
))
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't we actually validate that the payload is empty? Otherwise a malicious node could fill that section.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Execution doesn't care about it, so it wouldn't really matter, right? The next PR is bringing the real logic, so unless you can think of a way how this could be abused, I'd just leave it for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I suppose the idea is that a malicious block maker could fill the upgrade payload with garbage, slowing down the subnet (this up to 4 MB payload would have to be gossiped to everyone for no good reason).

OTOH, this is only a temporary situation, until we actually start putting useful content in the payload.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

fill the upgrade payload with garbage, slowing down the subnet

Yes exactly. I think it's best to always keep the builder and the validator in sync. And rejecting obvious malicious behaviour like here.

Comment thread rs/types/types/src/crypto/hash/tests.rs Outdated
assert_eq!(
hex::encode(hash.get_ref().0.as_slice()),
"764535296841f3db421a928cfadff3460be406d0182da64034eee623a9a97e99",
"c20a87578beb94df369dabfefc30c0d47d170c75d68236aae3b16335c0f21c4a",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's a red herring. As Leo mentioned, the better alternative would be to use a summary block for building the CUP instead of a data block here and below.

@frankdavid
frankdavid removed this pull request from stack #11656 September 24, 2026 13:33
Base automatically changed from frankdavid/fast-upgrades-consensus1 to master September 24, 2026 14:41

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants