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

feat: Checkpoint-light-client program #68

Merged
merged 34 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6cec13e
initial checkpointeths program
gshep Jun 10, 2024
ea435a4
checkpointeths-io
gshep Jun 11, 2024
5afc41b
add test using gclient
gshep Jun 12, 2024
220e237
keep checkpoints
gshep Jun 13, 2024
b96e3c3
refactoring: use named constants
gshep Jun 13, 2024
06d6520
add metadata
gshep Jun 13, 2024
d010c6c
add TypeInfo to several types
gshep Jun 13, 2024
f5bbf99
implement get checkpoint request
gshep Jun 13, 2024
d67375e
initial implementation of sync update handling
gshep Jun 13, 2024
881ebf2
use gear with extended bls381
gshep Jun 17, 2024
11bbcd7
sync_update
gshep Jun 17, 2024
a6b404c
fmt & clippy
gshep Jun 18, 2024
c3d625a
refactoring: introduce helper struct committee::Update
gshep Jun 19, 2024
c92d90f
fix Checkpoints: take gaps into account
gshep Jun 19, 2024
9268b9e
refactoring: keep next sync committee unconditionally
gshep Jun 19, 2024
32162ea
implement replay back
gshep Jun 21, 2024
0a16c0b
Merge remote-tracking branch 'origin/main'
gshep Jun 24, 2024
637f117
implement HandleResult::SyncUpdate
gshep Jun 24, 2024
7dab102
implement HandleResult::ReplayBack{Start,}
gshep Jun 24, 2024
50fca96
extend state: add info about replaying back
gshep Jun 24, 2024
a64c638
add missing chain data for tests
gshep Jun 26, 2024
ac66940
change branch of several deps
gshep Jun 26, 2024
254084b
rename Genesis::hash to validators_root and resolve todos
gshep Jun 26, 2024
5297a21
fix review remark
gshep Jun 27, 2024
df119c7
fix review remark: rename Genesis -> Network
gshep Jun 27, 2024
88df509
fix review remark: refactor CheckpointResult
gshep Jun 28, 2024
39341e7
fix review remarks
gshep Jun 28, 2024
29ff9db
fix review remarks
gshep Jun 28, 2024
7f0d8e7
fix review remarks
gshep Jun 28, 2024
60df628
Merge remote-tracking branch 'origin/main'
gshep Jul 15, 2024
f2dfa1c
fix review remark
gshep Jul 16, 2024
354894a
cargo fmt & clippy
gshep Jul 16, 2024
6c363d0
rename to checkpoint-light-client
gshep Jul 16, 2024
8f35d7a
cargo fmt
gshep Jul 16, 2024
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
205 changes: 131 additions & 74 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"circuits/*",
"ethereum-common",
"gear-programs/*",
"gear-programs/checkpoint-light-client/io",
]

resolver = "2"
Expand All @@ -30,6 +31,7 @@ ethereum-common = { path = "ethereum-common", default-features = false }
grc20_gateway = { path = "gear-programs/grc20-gateway" }
bridging_payment = { path = "gear-programs/bridging-payment" }
gear_proof_storage = { path = "gear-programs/proof-storage" }
checkpoint_light_client-io = { path = "gear-programs/checkpoint-light-client/io", default-features = false }

plonky2 = { git = "https://github.com/gear-tech/plonky2.git", rev = "4a620f4d79efe9233d0e7682df5a2fc625b5420e" }
plonky2_field = { git = "https://github.com/gear-tech/plonky2.git", rev = "4a620f4d79efe9233d0e7682df5a2fc625b5420e" }
Expand All @@ -41,11 +43,17 @@ curve25519-dalek = { git = "https://github.com/gear-tech/curve25519-dalek" }

ahash = "0.7.8"
anyhow = "1.0.86"
ark-bls12-381 = { version = "0.4.0", default-features = false }
ark-serialize = { version = "0.4", default-features = false }
ark-ec = { version = "0.4.2", default-features = false }
ark-ff = { version = "0.4.2", default-features = false }
ark-scale = { version = "0.0.12", default-features = false }
axum = "0.7.5"
bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] }
blake2 = "0.10.6"
bytes = "1.6.0"
clap = { version = "4.4.13", features = ["derive", "env"] }
circular-buffer = { version = "0.1.7", default-features = false, features = ["alloc"] }
derive_more = "0.99.17"
dotenv = "0.15.0"
env_logger = "0.9.0"
Expand All @@ -72,8 +80,9 @@ rand = { version = "0.8.5", default-features = false, features = ["getrandom"] }
rand_chacha = "0.3.1"
rayon = "1.5.3"
reqwest = "0.11.24"
scale-info = { version = "2.10", default-features = false }
serde = { version = "1.0", features = ["alloc", "derive"] }
ring = { git = "https://github.com/gear-tech/ring.git", branch = "gear-v0.17.8", default-features = false, features = ["alloc"] }
scale-info = { version = "2.10", default-features = false, features = ["derive"] }
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
serde_json = "1.0"
sha2 = "0.10"
static_assertions = "1.1.0"
Expand All @@ -85,18 +94,20 @@ unroll = "0.1.5"

# Gear/Substrate deps
gstd = { version = "1.4.1", features = ["nightly"] }
gmeta = "1.4.1"
gear-wasm-builder = { version = "1.4.1", default-features = false }
gsdk = { git = "https://github.com/gear-tech/gear.git", branch = "dn-pallet-gear-eth-bridge" }
gclient = { git = "https://github.com/gear-tech/gear.git", branch = "dn-pallet-gear-eth-bridge" }
gear-core = { git = "https://github.com/gear-tech/gear.git", branch = "dn-pallet-gear-eth-bridge" }
gbuiltin-bls381 = { git = "https://github.com/gear-tech/gear.git", branch = "dn-pallet-gear-eth-bridge" }
pallet-gear-eth-bridge-rpc-runtime-api = { git = "https://github.com/gear-tech/gear.git", branch = "dn-pallet-gear-eth-bridge", default-features = false, features = [
"std",
] }
subxt = "0.32.1"
sc-consensus-grandpa = { version = "0.10.0-dev", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-v1.3.0", default-features = false }
sp-runtime = { version = "24.0.0", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-v1.3.0", default-features = false }
sp-consensus-grandpa = { version = "4.0.0-dev", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-v1.3.0", default-features = false }
parity-scale-codec = { version = "3.6.4", default-features = false }
parity-scale-codec = { version = "3.6.4", default-features = false, features = ["derive"] }
trie-db = { version = "0.28.0", default-features = false }
sp-trie = { version = "22.0.0", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-v1.3.0", default-features = false }
sp-core = { version = "21.0.0", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-v1.3.0", default-features = false }
Expand Down
11 changes: 8 additions & 3 deletions ethereum-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ edition.workspace = true
description = "Various entities used in Ethereum ecosystem"

[dependencies]
parity-scale-codec = { workspace = true, features = ["derive"] }
parity-scale-codec = { workspace = true, features = ["bit-vec"] }
serde.workspace = true
tree_hash.workspace = true
tree_hash_derive.workspace = true
hex.workspace = true
hex = { workspace = true, features = ["alloc"] }
ethereum-types.workspace = true
derive_more.workspace = true
bitvec.workspace = true
scale-info = { workspace = true, features = ["bit-vec"] }
hex-literal.workspace = true
ring.workspace = true

[dev-dependencies]
hex-literal.workspace = true
serde_json.workspace = true

[features]
Expand All @@ -24,6 +26,9 @@ std = [
"parity-scale-codec/std",
"serde/std",
"tree_hash/std",
"hex/std",
"ethereum-types/std",
"bitvec/std",
"scale-info/std",
"ring/std",
]
110 changes: 2 additions & 108 deletions ethereum-common/src/base_types/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Inner = BitVec<u8, Lsb0>;
/// A homogenous collection of a fixed number of boolean values.
///
/// NOTE: a `Vector` of length `0` is illegal.
#[derive(PartialEq, Eq, Clone)]
#[derive(PartialEq, Eq, Clone, Decode, Encode, TypeInfo)]
pub struct Vector<const N: usize>(Inner);

impl<'de, const N: usize> Deserialize<'de> for Vector<N> {
Expand Down Expand Up @@ -174,49 +174,13 @@ impl<const N: usize> TreeHash for Vector<N> {
}
}

impl<const N: usize> Decode for Vector<N> {
fn decode<I: parity_scale_codec::Input>(
input: &mut I,
) -> Result<Self, parity_scale_codec::Error> {
let bytes = <Vec<u8> as Decode>::decode(input)?;

Ok(Self(BitVec::try_from_vec(bytes).map_err(|_| {
parity_scale_codec::Error::from(
"Failed to construct Vector<N>: source Vec<u8> is too long",
)
})?))
}
}

impl<const N: usize> Encode for Vector<N> {
fn encode(&self) -> Vec<u8> {
self.as_raw_slice().encode()
}

fn encode_to<W: parity_scale_codec::Output + ?Sized>(&self, dest: &mut W) {
self.as_raw_slice().encode_to(dest)
}

fn encoded_size(&self) -> usize {
self.as_raw_slice().encoded_size()
}

fn size_hint(&self) -> usize {
self.as_raw_slice().size_hint()
}

fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.as_raw_slice().using_encoded(f)
}
}

// +1 for length bit
fn bitlist_byte_length(bound: usize) -> usize {
(bound + BITS_PER_BYTE - 1 + 1) / BITS_PER_BYTE
}

/// A homogenous collection of a variable number of boolean values.
#[derive(PartialEq, Eq, Clone)]
#[derive(PartialEq, Eq, Clone, Decode, Encode, TypeInfo)]
pub struct List<const N: usize>(Inner);

impl<'de, const N: usize> Deserialize<'de> for List<N> {
Expand Down Expand Up @@ -270,25 +234,6 @@ impl<const N: usize> List<N> {
old
})
}

fn serialize_with_length(&self, buffer: &mut Vec<u8>, with_length_bit: bool) -> usize {
let start_len = buffer.len();
buffer.extend_from_slice(self.as_raw_slice());

if with_length_bit {
let element_count = self.len();
let marker_index = element_count % BITS_PER_BYTE;
if marker_index == 0 {
buffer.push(1u8);
} else {
let last = buffer.last_mut().expect("bitlist cannot be empty");
*last |= 1u8 << marker_index;
}
}

// SAFETY: checked subtraction is unnecessary, as buffer.len() > start_len; qed
buffer.len() - start_len
}
}

impl<const N: usize> Deref for List<N> {
Expand Down Expand Up @@ -386,54 +331,3 @@ impl<const N: usize> TreeHash for List<N> {
tree_hash::mix_in_length(&root, self.len())
}
}

impl<const N: usize> Decode for List<N> {
fn decode<I: parity_scale_codec::Input>(
input: &mut I,
) -> Result<Self, parity_scale_codec::Error> {
let bytes = <Vec<u8> as Decode>::decode(input)?;

Self::try_from(&bytes[..]).map_err(|_| {
parity_scale_codec::Error::from(
"Failed to construct Vector<N>: source Vec<u8> is too long",
)
})
}
}

impl<const N: usize> Encode for List<N> {
fn encode(&self) -> Vec<u8> {
let mut buffer = vec![];
self.serialize_with_length(&mut buffer, true);

buffer.encode()
}

fn encode_to<W: parity_scale_codec::Output + ?Sized>(&self, dest: &mut W) {
let mut buffer = vec![];
self.serialize_with_length(&mut buffer, true);

buffer.encode_to(dest)
}

fn encoded_size(&self) -> usize {
let mut buffer = vec![];
self.serialize_with_length(&mut buffer, true);

buffer.encoded_size()
}

fn size_hint(&self) -> usize {
let mut buffer = vec![];
self.serialize_with_length(&mut buffer, true);

buffer.size_hint()
}

fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
let mut buffer = vec![];
self.serialize_with_length(&mut buffer, true);

buffer.using_encoded(f)
}
}
2 changes: 1 addition & 1 deletion ethereum-common/src/base_types/byte_list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

#[derive(Debug, Clone, Decode, Encode)]
#[derive(Debug, Clone, Decode, Encode, TypeInfo)]
pub struct ByteList<const N: usize>(pub List<u8, N>);

impl<const N: usize> TryFrom<&[u8]> for ByteList<N> {
Expand Down
2 changes: 1 addition & 1 deletion ethereum-common/src/base_types/bytes_fixed.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

#[derive(Clone, Debug, Decode, Encode)]
#[derive(Clone, Debug, Decode, Encode, TypeInfo)]
pub struct BytesFixed<const N: usize>(pub FixedArray<u8, N>);

impl<const N: usize> AsRef<[u8]> for BytesFixed<N> {
Expand Down
3 changes: 2 additions & 1 deletion ethereum-common/src/base_types/fixed_array.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;

#[derive(Clone)]
#[derive(Clone, TypeInfo)]
#[scale_info(bounds(T: TypeInfo))]
pub struct FixedArray<T, const N: usize>(pub [T; N]);

impl<T: Debug, const N: usize> fmt::Debug for FixedArray<T, N> {
Expand Down
3 changes: 2 additions & 1 deletion ethereum-common/src/base_types/list.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::*;

/// A homogenous collection of a variable number of values.
#[derive(Clone)]
#[derive(Clone, TypeInfo)]
#[scale_info(bounds(T: TypeInfo))]
pub struct List<T, const N: usize> {
data: Vec<T>,
}
Expand Down
2 changes: 1 addition & 1 deletion ethereum-common/src/beacon/block_header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

#[derive(Debug, Clone, tree_hash_derive::TreeHash, Decode, Encode, Deserialize)]
#[derive(Debug, Clone, tree_hash_derive::TreeHash, Decode, Encode, Deserialize, TypeInfo)]
pub struct BlockHeader {
#[serde(deserialize_with = "utils::deserialize_u64")]
pub slot: u64,
Expand Down
8 changes: 7 additions & 1 deletion ethereum-common/src/beacon/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,14 @@ pub struct BlsToExecutionChange {
pub to_execution_address: Address,
}

#[derive(Debug, Clone, Decode, Encode, Deserialize, tree_hash_derive::TreeHash)]
#[derive(Debug, Clone, Decode, Encode, Deserialize, tree_hash_derive::TreeHash, TypeInfo)]
pub struct SyncAggregate {
pub sync_committee_bits: base_types::Bitvector<512>,
pub sync_committee_signature: SignatureBytes,
}

#[derive(Debug, Clone, Decode, Encode, Deserialize, tree_hash_derive::TreeHash, TypeInfo)]
pub struct SyncCommittee {
pub pubkeys: base_types::FixedArray<BLSPubKey, SYNC_COMMITTEE_SIZE>,
pub aggregate_pubkey: BLSPubKey,
}
7 changes: 7 additions & 0 deletions ethereum-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

pub mod base_types;
pub mod beacon;
pub mod merkle;
pub mod network;
pub mod utils;

#[cfg(not(feature = "std"))]
Expand All @@ -19,6 +21,11 @@ use core::{

pub use ethereum_types::U256;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use serde::{de, Deserialize};
pub use tree_hash::{self, Hash256};
use tree_hash::{TreeHash, TreeHashType};

pub const SLOTS_PER_EPOCH: u64 = 32;
pub const EPOCHS_PER_SYNC_COMMITTEE: u64 = 256;
pub const SYNC_COMMITTEE_SIZE: usize = 512;
Loading