Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
1,207 changes: 1,044 additions & 163 deletions contracts/near/Cargo.lock

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions contracts/near/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[workspace.package]
authors = ["Near One <info@nearone.org>"]
repository = "https://github.com/Near-One/rainbow-bridge"

[workspace]
members = [
"eth2-client",
Expand All @@ -22,12 +26,12 @@ borsh = "0.9.3"
rlp = "0.5.2"
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.

We also should update the project versions in all Cargo tomls

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

rlp-derive = "0.1.0"
ethereum-types = "0.14.1"
tree_hash = "0.5"
tree_hash_derive = "0.5"
ethereum_ssz = "0.5"
ethereum_ssz_derive = "0.5"
ethereum_serde_utils = "0.5"
ethereum_hashing = "1.0.0-beta.2"
tree_hash = "0.8"
tree_hash_derive = "0.8"
ethereum_ssz = "0.7"
ethereum_ssz_derive = "0.7"
ethereum_serde_utils = "0.7"
ethereum_hashing = "0.7.0"
derive_more = "^0.99.2"
hex = "0.4.2"
bitvec = "1.0.0"
Expand Down
18 changes: 18 additions & 0 deletions contracts/near/eth-prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ name = "eth-prover"
version = "2.0.0"
authors = ["Near Inc <hello@nearprotocol.com>"]
edition = "2021"
repository.workspace = true

# fields to configure build with WASM reproducibility, according to specs
# in https://github.com/near/NEPs/blob/master/neps/nep-0330.md
[package.metadata.near.reproducible_build]
# docker image, descriptor of build environment
image = "sourcescan/cargo-near:0.13.2-rust-1.84.0"
# tag after colon above serves only descriptive purpose; image is identified by digest
image_digest = "sha256:b41cb89907f92b114da9e2be4e109bff30ab792c22ddcbd2a4cff8e340cb9acb"
# list of environment variables names, whose values, if set, will be used as external build parameters
# in a reproducible manner
# supported by `sourcescan/cargo-near:0.10.1-rust-1.82.0` image or later images
passed_env = []
# build command inside of docker container
# if docker image from default gallery is used https://hub.docker.com/r/sourcescan/cargo-near/tags,
# the command may be any combination of flags of `cargo-near`,
# supported by respective version of binary inside the container besides `--no-locked` flag
container_build_command = ["cargo", "near", "build", "non-reproducible-wasm", "--locked"]

[lib]
crate-type = ["cdylib", "rlib"]
Expand Down
2 changes: 1 addition & 1 deletion contracts/near/eth-prover/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "1.69.0"
channel = "1.84.0"
2 changes: 1 addition & 1 deletion contracts/near/eth-types/src/eth2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl From<HeaderUpdate> for ExtendedBeaconBlockHeader {
let root = item.beacon_header.tree_hash_root();
ExtendedBeaconBlockHeader {
header: item.beacon_header,
beacon_block_root: H256(root),
beacon_block_root: H256(root.0.into()),
execution_block_hash: item.execution_block_hash,
}
}
Expand Down
12 changes: 11 additions & 1 deletion contracts/near/eth-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl TreeHash for H256 {
}

fn tree_hash_root(&self) -> tree_hash::Hash256 {
(*self).0
(*self).0.0.into()
}
}

Expand Down Expand Up @@ -173,6 +173,8 @@ pub struct BlockHeader {
pub excess_blob_gas: Option<u64>,
#[cfg_attr(all(feature = "eth2", not(target_arch = "wasm32")), serde(default))]
pub parent_beacon_block_root: Option<H256>,
#[cfg_attr(all(feature = "eth2", not(target_arch = "wasm32")), serde(default))]
pub requests_hash: Option<H256>,

pub hash: Option<H256>,
pub partial_hash: Option<H256>,
Expand Down Expand Up @@ -225,6 +227,9 @@ impl BlockHeader {
if self.parent_beacon_block_root.is_some() {
list_size += 1;
}
if self.requests_hash.is_some() {
list_size += 1;
}

stream.begin_list(list_size);

Expand Down Expand Up @@ -266,6 +271,10 @@ impl BlockHeader {
if let Some(parent_beacon_block_root) = &self.parent_beacon_block_root {
stream.append(parent_beacon_block_root);
}

if let Some(requests_hash) = &self.requests_hash {
stream.append(requests_hash);
}
}

pub fn calculate_hash(&self) -> H256 {
Expand Down Expand Up @@ -307,6 +316,7 @@ impl RlpDecodable for BlockHeader {
blob_gas_used: serialized.val_at(17).ok(),
excess_blob_gas: serialized.val_at(18).ok(),
parent_beacon_block_root: serialized.val_at(19).ok(),
requests_hash: serialized.val_at(20).ok(),
hash: None,
partial_hash: None,
};
Expand Down
2 changes: 1 addition & 1 deletion contracts/near/eth-types/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ macro_rules! vec_wrapper_impl_tree_hash {

for item in &self.0 {
hasher
.write(item.tree_hash_root().as_bytes())
.write(item.tree_hash_root().as_slice())
.expect("ssz_types vec should not contain more elements than max");
}

Expand Down
18 changes: 18 additions & 0 deletions contracts/near/eth2-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ name = "eth2-client"
version = "0.4.0"
authors = ["Aurora <hello@aurora.dev>"]
edition = "2021"
repository.workspace = true

# fields to configure build with WASM reproducibility, according to specs
# in https://github.com/near/NEPs/blob/master/neps/nep-0330.md
[package.metadata.near.reproducible_build]
# docker image, descriptor of build environment
image = "sourcescan/cargo-near:0.13.2-rust-1.84.0"
# tag after colon above serves only descriptive purpose; image is identified by digest
image_digest = "sha256:b41cb89907f92b114da9e2be4e109bff30ab792c22ddcbd2a4cff8e340cb9acb"
# list of environment variables names, whose values, if set, will be used as external build parameters
# in a reproducible manner
# supported by `sourcescan/cargo-near:0.10.1-rust-1.82.0` image or later images
passed_env = []
# build command inside of docker container
# if docker image from default gallery is used https://hub.docker.com/r/sourcescan/cargo-near/tags,
# the command may be any combination of flags of `cargo-near`,
# supported by respective version of binary inside the container besides `--no-locked` flag
container_build_command = ["cargo", "near", "build", "non-reproducible-wasm", "--locked"]

[lib]
crate-type = ["cdylib", "rlib"]
Expand Down
2 changes: 1 addition & 1 deletion contracts/near/eth2-client/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "1.69.0"
channel = "1.84.0"
34 changes: 28 additions & 6 deletions contracts/near/eth2-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,13 @@ impl Eth2Client {
)
);

let config = NetworkConfig::new(&self.network);

// Verify that the `finality_branch`, confirms `finalized_header`
// to match the finalized checkpoint root saved in the state of `attested_header`.
let generalized_index = config.get_generalized_index_constants(
update.finality_update.header_update.beacon_header.slot,
);
require!(
verify_merkle_proof(
H256(
Expand All @@ -457,15 +462,17 @@ impl Eth2Client {
.header_update
.beacon_header
.tree_hash_root()
.0
.into()
),
&update.finality_update.finality_branch,
FINALITY_TREE_DEPTH.try_into().unwrap(),
FINALITY_TREE_INDEX.try_into().unwrap(),
generalized_index.finality_tree_depth.try_into().unwrap(),
generalized_index.finality_tree_index.try_into().unwrap(),
update.attested_beacon_header.state_root
),
"Invalid finality proof"
);
let config = NetworkConfig::new(&self.network);

require!(
config.validate_beacon_block_header_update(&update.finality_update.header_update),
"Invalid execution block hash proof"
Expand All @@ -474,16 +481,31 @@ impl Eth2Client {
// Verify that the `next_sync_committee`, if present, actually is the next sync committee saved in the
// state of the `active_header`
if update_period != finalized_period {
let generalized_index =
config.get_generalized_index_constants(update.attested_beacon_header.slot);

let sync_committee_update = update
.sync_committee_update
.as_ref()
.unwrap_or_else(|| env::panic_str("The sync committee update is missed"));
require!(
verify_merkle_proof(
H256(sync_committee_update.next_sync_committee.tree_hash_root()),
H256(
sync_committee_update
.next_sync_committee
.tree_hash_root()
.0
.into()
),
&sync_committee_update.next_sync_committee_branch,
SYNC_COMMITTEE_TREE_DEPTH.try_into().unwrap(),
SYNC_COMMITTEE_TREE_INDEX.try_into().unwrap(),
generalized_index
.sync_committee_tree_depth
.try_into()
.unwrap(),
generalized_index
.sync_committee_tree_index
.try_into()
.unwrap(),
update.attested_beacon_header.state_root
),
"Invalid next sync committee proof"
Expand Down
57 changes: 48 additions & 9 deletions contracts/near/eth2-utility/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ pub const MIN_SYNC_COMMITTEE_PARTICIPANTS: u64 = 1;
pub const SLOTS_PER_EPOCH: u64 = 32;
pub const DOMAIN_SYNC_COMMITTEE: DomainType = [0x07, 0x00, 0x00, 0x00];

pub const FINALIZED_ROOT_INDEX: u32 = 105;
pub const NEXT_SYNC_COMMITTEE_INDEX: u32 = 55;
pub const FINALITY_TREE_DEPTH: u32 = floorlog2(FINALIZED_ROOT_INDEX);
pub const FINALITY_TREE_INDEX: u32 = get_subtree_index(FINALIZED_ROOT_INDEX);
pub const SYNC_COMMITTEE_TREE_DEPTH: u32 = floorlog2(NEXT_SYNC_COMMITTEE_INDEX);
pub const SYNC_COMMITTEE_TREE_INDEX: u32 = get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX);

pub struct ProofSize {
pub beacon_block_body_tree_depth: usize,
pub l1_beacon_block_body_tree_execution_payload_index: usize,
Expand All @@ -28,6 +21,13 @@ pub struct ProofSize {
pub execution_proof_size: usize,
}

pub struct GeneralizedIndex {
pub finality_tree_depth: u32,
pub finality_tree_index: u32,
pub sync_committee_tree_depth: u32,
pub sync_committee_tree_index: u32,
}

#[derive(PartialEq, BorshSerialize, BorshDeserialize)]
pub enum Network {
Mainnet,
Expand Down Expand Up @@ -55,6 +55,8 @@ pub struct NetworkConfig {
pub capella_fork_epoch: u64,
pub deneb_fork_version: ForkVersion,
pub deneb_fork_epoch: u64,
pub electra_fork_version: ForkVersion,
pub electra_fork_epoch: u64,
}

impl NetworkConfig {
Expand All @@ -72,6 +74,8 @@ impl NetworkConfig {
capella_fork_epoch: 194048,
deneb_fork_version: [0x04, 0x00, 0x00, 0x00],
deneb_fork_epoch: 269568,
electra_fork_version: [0x00, 0x00, 0x00, 0x00], // Not supported
electra_fork_epoch: 0, // Not supported
},
Network::Goerli => Self {
genesis_validators_root: [
Expand All @@ -85,6 +89,8 @@ impl NetworkConfig {
capella_fork_epoch: 162304,
deneb_fork_version: [0x04, 0x00, 0x10, 0x20],
deneb_fork_epoch: 231680,
electra_fork_version: [0x00, 0x00, 0x00, 0x00], // Not supported
electra_fork_epoch: 0, // Not supported
},
Network::Sepolia => Self {
genesis_validators_root: [
Expand All @@ -98,11 +104,17 @@ impl NetworkConfig {
capella_fork_epoch: 56832,
deneb_fork_version: [0x90, 0x00, 0x00, 0x73],
deneb_fork_epoch: 132608,
electra_fork_version: [0x90, 0x00, 0x00, 0x74],
electra_fork_epoch: 222464,
},
}
}

pub fn compute_fork_version(&self, epoch: Epoch) -> Option<ForkVersion> {
if epoch >= self.electra_fork_epoch {
return Some(self.electra_fork_version);
}

if epoch >= self.deneb_fork_epoch {
return Some(self.deneb_fork_version);
}
Expand Down Expand Up @@ -144,6 +156,31 @@ impl NetworkConfig {
}
}

pub const fn get_generalized_index_constants(&self, slot: Slot) -> GeneralizedIndex {
pub const FINALIZED_ROOT_INDEX: u32 = 105;
pub const NEXT_SYNC_COMMITTEE_INDEX: u32 = 55;
pub const FINALIZED_ROOT_INDEX_ELECTRA: u32 = 169;
pub const NEXT_SYNC_COMMITTEE_INDEX_ELECTRA: u32 = 87;

let epoch = compute_epoch_at_slot(slot);

if epoch >= self.electra_fork_epoch {
GeneralizedIndex {
finality_tree_depth: floorlog2(FINALIZED_ROOT_INDEX_ELECTRA),
finality_tree_index: get_subtree_index(FINALIZED_ROOT_INDEX_ELECTRA),
sync_committee_tree_depth: floorlog2(NEXT_SYNC_COMMITTEE_INDEX_ELECTRA),
sync_committee_tree_index: get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX_ELECTRA),
}
} else {
GeneralizedIndex {
finality_tree_depth: floorlog2(FINALIZED_ROOT_INDEX),
finality_tree_index: get_subtree_index(FINALIZED_ROOT_INDEX),
sync_committee_tree_depth: floorlog2(NEXT_SYNC_COMMITTEE_INDEX),
sync_committee_tree_index: get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX),
}
}
}

pub fn compute_proof_size_by_slot(&self, slot: Slot) -> ProofSize {
self.compute_proof_size(compute_epoch_at_slot(slot))
}
Expand Down Expand Up @@ -209,7 +246,7 @@ pub fn compute_domain(
domain[0..4].copy_from_slice(&domain_constant);
domain[4..].copy_from_slice(
fork_data_root
.as_bytes()
.as_slice()
.get(..28)
.expect("fork has is 32 bytes so first 28 bytes should exist"),
);
Expand All @@ -223,7 +260,9 @@ pub fn compute_signing_root(object_root: H256, domain: H256) -> H256 {
object_root,
domain,
}
.tree_hash_root(),
.tree_hash_root()
.0
.into(),
)
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/near/eth2_hashing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ethereum_hashing"
version = "1.0.0-beta.2"
version = "0.7.0"
authors = ["Aurora <hello@aurora.dev>"]
edition = "2021"
license = "Apache-2.0"
Expand Down
Binary file modified contracts/near/res/eth2_client.wasm
100755 → 100644
Binary file not shown.
Binary file modified contracts/near/res/eth_prover.wasm
100755 → 100644
Binary file not shown.
2 changes: 1 addition & 1 deletion contracts/near/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "1.68.0"
channel = "1.84.0"
Loading