Skip to content

Commit

Permalink
fix(program): constrain sync commitee on updates (#25)
Browse files Browse the repository at this point in the history
* fix: constrain start sync committee on updates

* fix: extraneous err

* chore: comment

* feat; update elf

* contract

---------

Co-authored-by: ratankaliani <[email protected]>
Co-authored-by: Ratan Kaliani <[email protected]>
  • Loading branch information
3 people authored Jan 29, 2025
1 parent 990a93c commit dc816e6
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 0 deletions.
18 changes: 18 additions & 0 deletions contracts/src/SP1Helios.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ contract SP1Helios {
uint256 newHead;
bytes32 prevHeader;
uint256 prevHead;
// Hash of the sync committee at the new head.
bytes32 syncCommitteeHash;
// Hash of the current sync committee that signed the previous update.
bytes32 startSyncCommitteeHash;
}

struct InitParams {
Expand All @@ -72,6 +75,7 @@ contract SP1Helios {
error SyncCommitteeAlreadySet(uint256 period);
error HeaderRootAlreadySet(uint256 slot);
error StateRootAlreadySet(uint256 slot);
error SyncCommitteeStartMismatch(bytes32 given, bytes32 expected);

constructor(InitParams memory params) {
GENESIS_VALIDATORS_ROOT = params.genesisValidatorsRoot;
Expand Down Expand Up @@ -99,17 +103,31 @@ contract SP1Helios {
revert SlotBehindHead(po.newHead);
}

uint256 currentPeriod = getSyncCommitteePeriod(head);

// Note: We should always have a sync committee for the current head.
// The "start" sync committee hash is the hash of the sync committee that should sign the next update.
bytes32 currentSyncCommitteeHash = syncCommittees[currentPeriod];
if (currentSyncCommitteeHash != po.startSyncCommitteeHash) {
revert SyncCommitteeStartMismatch(po.startSyncCommitteeHash, currentSyncCommitteeHash);
}

// Verify the proof with the associated public values. This will revert if proof invalid.
ISP1Verifier(verifier).verifyProof(heliosProgramVkey, publicValues, proof);

// Check that the new header hasnt been set already.
head = po.newHead;
if (headers[po.newHead] != bytes32(0)) {
revert HeaderRootAlreadySet(po.newHead);
}

// Check that the new state root hasnt been set already.
headers[po.newHead] = po.newHeader;
if (executionStateRoots[po.newHead] != bytes32(0)) {
revert StateRootAlreadySet(po.newHead);
}

// Finally set the new state root.
executionStateRoots[po.newHead] = po.executionStateRoot;
emit HeadUpdate(po.newHead, po.newHeader);

Expand Down
Binary file modified elf/sp1-helios-elf
Binary file not shown.
1 change: 1 addition & 0 deletions primitives/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ sol! {
bytes32 prevHeader;
uint256 prevHead;
bytes32 syncCommitteeHash;
bytes32 startSyncCommitteeHash;
}
}
2 changes: 2 additions & 0 deletions program/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn main() {
forks,
} = serde_cbor::from_slice(&encoded_inputs).unwrap();

let start_sync_committee_hash = store.current_sync_committee.tree_hash_root();
let prev_header: B256 = store.finalized_header.beacon().tree_hash_root();
let prev_head = store.finalized_header.beacon().slot;

Expand Down Expand Up @@ -84,6 +85,7 @@ pub fn main() {
prevHeader: prev_header,
prevHead: U256::from(prev_head),
syncCommitteeHash: sync_committee_hash,
startSyncCommitteeHash: start_sync_committee_hash,
};
sp1_zkvm::io::commit_slice(&proof_outputs.abi_encode());
}

0 comments on commit dc816e6

Please sign in to comment.