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

Beacon light client follow Capella light client spec #321

Merged
merged 9 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions contracts/bridge/e2e/helper/hashtest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { toHexString, ByteVectorType, ByteListType } = require('@chainsafe/ssz')

const hash = (typ, input) => {
const value = typ.fromJson(input)
return toHexString(typ.hashTreeRoot(value))
}

const LogsBloom = new ByteVectorType(256)
const ExtraData = new ByteListType(32)
const logs_bloom = "0x55a3c12245fa205614806420a6195141710230824c0e0882a14934606607042290442511508c219850183b4408c0210007294023da0438c19310c082197c2b044082bd18828088d87932d608420c00706c1034844c644c316e82ce468a74862b9ea8ac8003028089054318a090207d39c0d5082f881504676304a1b8080cd8042a048e7a4110c50011616001020a04221000b70bb98004887e28807b889300215b49619241086c5e406e3af0dbd6041b0ee00a7e60a601f8802b2a36a028aa92c11a161a1606051b2810e2123451121663c406115342b09b25051d2688406148d8396e8c8b0581a20284d58240010d2804d8010d332ac0519013302991d8d461"
const extra_data = "0xd883010b05846765746888676f312e32302e32856c696e7578"
const h1 = hash(LogsBloom, logs_bloom)
console.log(h1)
const h2 = hash(ExtraData, extra_data)
console.log(h2)
11 changes: 2 additions & 9 deletions contracts/bridge/src/migrate/BeaconLightClientMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
pragma solidity 0.8.17;

import "../truth/eth/BeaconLightClient.sol";
import "../truth/eth/ExecutionLayer.sol";


interface IEthereumStorageVerifier {
Expand All @@ -28,29 +27,25 @@ interface IEthereumStorageVerifier {

contract BeaconLightClientMigrator {
BeaconLightClient public new_beacon_lc;
ExecutionLayer public new_execution_layer;

address public immutable HELIX_DAO;
address public immutable OLD_BEACON_LC;
address public immutable ETHEREUM_STORAGE_VERIFIER;
address public immutable BLS_PRECOMPILE;
bytes32 public immutable GENESIS_VALIDATORS_ROOT;
uint64 public immutable CAPELLA_FORK_EPOCH;

constructor(
address helix_dao,
address old_lc,
address verifier,
address bls,
bytes32 genesis_validators_root,
uint64 capella_for_epoch
bytes32 genesis_validators_root
) {
HELIX_DAO = helix_dao;
OLD_BEACON_LC = old_lc;
ETHEREUM_STORAGE_VERIFIER = verifier;
BLS_PRECOMPILE = bls;
GENESIS_VALIDATORS_ROOT = genesis_validators_root;
CAPELLA_FORK_EPOCH = capella_for_epoch;
}

function migrate() public {
Expand Down Expand Up @@ -79,10 +74,8 @@ contract BeaconLightClientMigrator {
current_sync_committee_hash,
GENESIS_VALIDATORS_ROOT
);
// new ExecutionLayer
new_execution_layer = new ExecutionLayer(address(new_beacon_lc), CAPELLA_FORK_EPOCH);
// change light client
IEthereumStorageVerifier(ETHEREUM_STORAGE_VERIFIER).changeLightClient(address(new_execution_layer));
IEthereumStorageVerifier(ETHEREUM_STORAGE_VERIFIER).changeLightClient(address(new_beacon_lc));

returnSetter();
}
Expand Down
146 changes: 11 additions & 135 deletions contracts/bridge/src/spec/BeaconChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,89 +68,18 @@ contract BeaconChain is MerkleProof {
bytes32 body_root;
}

/// @notice Beacon block body in Bellatrix
/// @param randao_reveal Randao reveal
/// @param eth1_data Eth1 data vote
/// @param graffiti Arbitrary data
/// @param proposer_slashings Proposer slashings
/// @param attester_slashings Attester slashings
/// @param attestations Attestations
/// @param deposits Deposits
/// @param voluntary_exits Voluntary exits
/// @param sync_aggregate Sync aggregate
/// @param execution_payload Execution payload [New in Bellatrix]
struct BeaconBlockBodyBellatrix {
bytes32 randao_reveal;
bytes32 eth1_data;
bytes32 graffiti;
bytes32 proposer_slashings;
bytes32 attester_slashings;
bytes32 attestations;
bytes32 deposits;
bytes32 voluntary_exits;
bytes32 sync_aggregate;
ExecutionPayloadBellatrix execution_payload;
}

/// @notice Beacon block body in Capella
/// @param randao_reveal Randao reveal
/// @param eth1_data Eth1 data vote
/// @param graffiti Arbitrary data
/// @param proposer_slashings Proposer slashings
/// @param attester_slashings Attester slashings
/// @param attestations Attestations
/// @param deposits Deposits
/// @param voluntary_exits Voluntary exits
/// @param sync_aggregate Sync aggregate
/// @param execution_payload Execution payload
/// @param bls_to_execution_changes Capella operations [New in Capella]
struct BeaconBlockBodyCapella {
bytes32 randao_reveal;
bytes32 eth1_data;
bytes32 graffiti;
bytes32 proposer_slashings;
bytes32 attester_slashings;
bytes32 attestations;
bytes32 deposits;
bytes32 voluntary_exits;
bytes32 sync_aggregate;
ExecutionPayloadCapella execution_payload;
bytes32 bls_to_execution_changes;
/// @notice Light client header
/// @param beacon Beacon block header
/// @param execution Execution payload header corresponding to `beacon.body_root` [New in Capella]
/// @param execution_branch Execution payload header proof corresponding to `beacon.body_root` [New in Capella]
struct LightClientHeader {
BeaconBlockHeader beacon;
ExecutionPayloadHeader execution;
bytes32[] execution_branch;
}

/// @notice Execution payload in Bellatrix
/// @param parent_hash Parent hash
/// @param fee_recipient Beneficiary
/// @param state_root State root
/// @param receipts_root Receipts root
/// @param logs_bloom Logs bloom
/// @param prev_randao Difficulty
/// @param block_number Number
/// @param gas_limit Gas limit
/// @param gas_used Gas used
/// @param timestamp Timestamp
/// @param extra_data Extra data
/// @param base_fee_per_gas Base fee per gas
/// @param block_hash Hash of execution block
/// @param transactions Transactions
struct ExecutionPayloadBellatrix {
bytes32 parent_hash;
address fee_recipient;
bytes32 state_root;
bytes32 receipts_root;
bytes32 logs_bloom;
bytes32 prev_randao;
uint64 block_number;
uint64 gas_limit;
uint64 gas_used;
uint64 timestamp;
bytes32 extra_data;
uint256 base_fee_per_gas;
bytes32 block_hash;
bytes32 transactions;
}

/// @notice Execution payload in Capella
/// @notice Execution payload header in Capella
/// @param parent_hash Parent hash
/// @param fee_recipient Beneficiary
/// @param state_root State root
Expand All @@ -166,7 +95,7 @@ contract BeaconChain is MerkleProof {
/// @param block_hash Hash of execution block
/// @param transactions_root Root of transactions
/// @param withdrawals_root Root of withdrawals [New in Capella]
struct ExecutionPayloadCapella {
struct ExecutionPayloadHeader {
bytes32 parent_hash;
address fee_recipient;
bytes32 state_root;
Expand Down Expand Up @@ -246,61 +175,8 @@ contract BeaconChain is MerkleProof {
return merkle_root(leaves);
}

/// @notice Return hash tree root of beacon block body in Bellatrix
function hash_tree_root(BeaconBlockBodyBellatrix memory beacon_block_body) internal pure returns (bytes32) {
bytes32[] memory leaves = new bytes32[](10);
leaves[0] = beacon_block_body.randao_reveal;
leaves[1] = beacon_block_body.eth1_data;
leaves[2] = beacon_block_body.graffiti;
leaves[3] = beacon_block_body.proposer_slashings;
leaves[4] = beacon_block_body.attester_slashings;
leaves[5] = beacon_block_body.attestations;
leaves[6] = beacon_block_body.deposits;
leaves[7] = beacon_block_body.voluntary_exits;
leaves[8] = beacon_block_body.sync_aggregate;
leaves[9] = hash_tree_root(beacon_block_body.execution_payload);
return merkle_root(leaves);
}

/// @notice Return hash tree root of beacon block body in Capella
function hash_tree_root(BeaconBlockBodyCapella memory beacon_block_body) internal pure returns (bytes32) {
bytes32[] memory leaves = new bytes32[](11);
leaves[0] = beacon_block_body.randao_reveal;
leaves[1] = beacon_block_body.eth1_data;
leaves[2] = beacon_block_body.graffiti;
leaves[3] = beacon_block_body.proposer_slashings;
leaves[4] = beacon_block_body.attester_slashings;
leaves[5] = beacon_block_body.attestations;
leaves[6] = beacon_block_body.deposits;
leaves[7] = beacon_block_body.voluntary_exits;
leaves[8] = beacon_block_body.sync_aggregate;
leaves[9] = hash_tree_root(beacon_block_body.execution_payload);
leaves[10] = beacon_block_body.bls_to_execution_changes;
return merkle_root(leaves);
}

/// @notice Return hash tree root of execution payload in Bellatrix
function hash_tree_root(ExecutionPayloadBellatrix memory execution_payload) internal pure returns (bytes32) {
bytes32[] memory leaves = new bytes32[](14);
leaves[0] = execution_payload.parent_hash;
leaves[1] = bytes32(bytes20(execution_payload.fee_recipient));
leaves[2] = execution_payload.state_root;
leaves[3] = execution_payload.receipts_root;
leaves[4] = execution_payload.logs_bloom;
leaves[5] = execution_payload.prev_randao;
leaves[6] = bytes32(to_little_endian_64(execution_payload.block_number));
leaves[7] = bytes32(to_little_endian_64(execution_payload.gas_limit));
leaves[8] = bytes32(to_little_endian_64(execution_payload.gas_used));
leaves[9] = bytes32(to_little_endian_64(execution_payload.timestamp));
leaves[10] = execution_payload.extra_data;
leaves[11] = to_little_endian_256(execution_payload.base_fee_per_gas);
leaves[12] = execution_payload.block_hash;
leaves[13] = execution_payload.transactions;
return merkle_root(leaves);
}

/// @notice Return hash tree root of execution payload in Capella
function hash_tree_root(ExecutionPayloadCapella memory execution_payload) internal pure returns (bytes32) {
function hash_tree_root(ExecutionPayloadHeader memory execution_payload) internal pure returns (bytes32) {
bytes32[] memory leaves = new bytes32[](15);
leaves[0] = execution_payload.parent_hash;
leaves[1] = bytes32(bytes20(execution_payload.fee_recipient));
Expand Down
6 changes: 3 additions & 3 deletions contracts/bridge/src/spec/BeaconLightClientUpdate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ contract BeaconLightClientUpdate is BeaconChain {
/// @param attested_header Header attested to by the sync committee
/// @param signature_sync_committee Sync committee corresponding to sign attested header
/// @param finalized_header The finalized beacon block header
/// @param finality_branch Finalized header corresponding to `attested_header.state_root`
/// @param finality_branch Finalized header proof corresponding to `attested_header.state_root`
/// @param sync_aggregate Sync committee aggregate signature
/// @param fork_version Fork version for the aggregate signature
/// @param signature_slot Slot at which the aggregate signature was created (untrusted)
struct FinalizedHeaderUpdate {
BeaconBlockHeader attested_header;
LightClientHeader attested_header;
SyncCommittee signature_sync_committee;
BeaconBlockHeader finalized_header;
LightClientHeader finalized_header;
bytes32[] finality_branch;
SyncAggregate sync_aggregate;
bytes4 fork_version;
Expand Down
4 changes: 2 additions & 2 deletions contracts/bridge/src/test/spec/BeaconChain.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ contract BeaconChainTest is DSTest, SyncCommitteePreset {
SyncCommittee memory case1 = sync_committee_case1();
assertEq(hash_tree_root(case1), 0x5cf5804f5a8dc680445f5efd4069859f3c65dd2db869f1d091f454008f6d7ab7);

SyncCommittee memory case5 = sync_committee_case5();
assertEq(hash_tree_root(case5), 0xdf643843d074b6e1fa955ef78231b7d952795fce81a5153dd4e647482b9a52ff);
SyncCommittee memory case4 = sync_committee_case4();
assertEq(hash_tree_root(case4), 0x344e99e6b29e1ffa0481053f25004cd8a0e0417804f3a22eaecb9e0d2948fb70);
}


Expand Down
Loading