Skip to content

Retain the block owner's proposal signature alongside certificates (#456)#6589

Draft
ma2bd wants to merge 5 commits into
mainfrom
ma2bd/456-retain-owner-signature
Draft

Retain the block owner's proposal signature alongside certificates (#456)#6589
ma2bd wants to merge 5 commits into
mainfrom
ma2bd/456-retain-owner-signature

Conversation

@ma2bd

@ma2bd ma2bd commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Motivation

Fixes #456. When a block proposal is turned into a certificate, the chain owner's signature is discarded — a confirmed block retains authenticated_owner but nothing backs it. As a result, the authorization of a block (and of the authenticated_owner claims on its outgoing messages) is attested only by the validator quorum: an auditor replaying the chain, or any party distrusting a (possibly revoked) committee, cannot verify that a chain owner ever authorized the block.

Proposal

Retain the owner's signature alongside certificates, and make it a validity condition for blocks that declare an authenticated_owner:

  • New OwnerAuthorization { round, signature }: the owner's signature over the initial, outcome-less ProposalContent that introduced the block. Every block's first proposal has outcome: None (fresh proposals and fast-round retries alike, and retry-regular chains bottom out in one), and that signature is exactly the one validators checked against authenticated_owner at proposal time. Given the block, anyone can reconstruct the signed content (Block::to_proposed() + the recorded round) and verify it — no extra data needed.
  • The signature is carried as an unhashed optional field on GenericCertificate and on LiteCertificate, per the issue's "bonus point": it must not be covered by the block hash, since the same block can be authorized by proposals in different rounds. Carrying it on LiteCertificate is load-bearing: storage persists certificates as (lite certificate + block) and validators rebuild full certificates from lite certificates and cached values, so the evidence survives those paths.
  • Validity rule: a certified block with authenticated_owner: Some(owner) is rejected (ChainError::MissingOwnerAuthorization) unless the certificate retains a valid signature by owner. Enforced in process_validated_block, process_confirmed_block (covering the preprocess and checkpoint-restore dispatches), and on OriginalProposal::Regular retry proposals — the latter prevents invalid or missing evidence from entering locking blocks and only surfacing at finalization. Blocks without an authenticated owner may omit the signature (pre-existing certificates, provenance-optional blocks), but if present it must verify.
  • Client threading: submit_block_proposal attaches the authorization derived from the proposal (fresh → its own signature, fast-retry → the original fast-round signature); finalize_block and retry-regular proposals carry it over from the validated certificate.
  • Wire format: optional bytes owner_authorization on the gRPC Certificate (field 5) and LiteCertificate (field 7); BCS certificate formats gain the optional field (formats.yaml regenerated).

Note: this changes the stored and transmitted certificate formats, so it requires a new deployment; previously stored certificates do not deserialize.

Test Plan

  • New unit test owner_authorization_verifies_against_block: signature round-trip, wrong round, wrong signer vs. authenticated_owner, missing authorization rejected for authenticated blocks and accepted otherwise.
  • Client tests assert end-to-end retention: the fast-path certificate carries a verifying authorization, and in test_finalize_locked_block_with_blobs the certificate finalized by client 2B still verifies against owner 2A's signature (carried across the validated certificate and the retry).
  • The testing PartialEq on certificates now includes the field, so check_that_validators_have_certificate proves validators store byte-identical evidence (this caught the lite-certificate propagation gap during development).
  • Worker tests gained an owner-key registry in TestEnvironment so self-certified test blocks carry valid authorizations; the mandatory rule is exercised by all certificate-handling tests.
  • cargo test -p linera-chain -p linera-core -p linera-rpc -p linera-storage all pass; clippy clean.

Release Plan

  • Backporting is not possible but we may want to deploy a new devnet and release a new SDK soon.

Links

@ma2bd ma2bd marked this pull request as draft July 4, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Do not erase signature of block owners

1 participant