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

Add support for deploying a mock light client contract #1322

Merged
merged 10 commits into from
Apr 17, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions contract-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub mod fee_contract;
pub mod hot_shot;
pub mod i_plonk_verifier;
pub mod light_client;
pub mod light_client_mock;
pub mod light_client_state_update_vk;
pub mod light_client_state_update_vk_mock;
pub mod plonk_verifier;
pub mod shared_types;
23 changes: 0 additions & 23 deletions contract-bindings/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2762,27 +2762,4 @@ pub mod light_client {
Hash,
)]
pub struct VotingThresholdReturn(pub ::ethers::core::types::U256);
///`LightClientState(uint64,uint64,uint256,uint256,uint256,uint256,uint256,uint256)`
#[derive(
Clone,
::ethers::contract::EthAbiType,
::ethers::contract::EthAbiCodec,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
pub struct LightClientState {
pub view_num: u64,
pub block_height: u64,
pub block_comm_root: ::ethers::core::types::U256,
pub fee_ledger_comm: ::ethers::core::types::U256,
pub stake_table_bls_key_comm: ::ethers::core::types::U256,
pub stake_table_schnorr_key_comm: ::ethers::core::types::U256,
pub stake_table_amount_comm: ::ethers::core::types::U256,
pub threshold: ::ethers::core::types::U256,
}
}
2,915 changes: 2,915 additions & 0 deletions contract-bindings/src/light_client_mock.rs

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions contract-bindings/src/light_client_state_update_vk_mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
pub use light_client_state_update_vk_mock::*;
/// This module was auto-generated with ethers-rs Abigen.
/// More information at: <https://github.com/gakonst/ethers-rs>
#[allow(
clippy::enum_variant_names,
clippy::too_many_arguments,
clippy::upper_case_acronyms,
clippy::type_complexity,
dead_code,
non_camel_case_types
)]
pub mod light_client_state_update_vk_mock {
#[allow(deprecated)]
fn __abi() -> ::ethers::core::abi::Abi {
::ethers::core::abi::ethabi::Contract {
constructor: ::core::option::Option::None,
functions: ::std::collections::BTreeMap::new(),
events: ::std::collections::BTreeMap::new(),
errors: ::std::collections::BTreeMap::new(),
receive: false,
fallback: false,
}
}
///The parsed JSON ABI of the contract.
pub static LIGHTCLIENTSTATEUPDATEVKMOCK_ABI: ::ethers::contract::Lazy<
::ethers::core::abi::Abi,
> = ::ethers::contract::Lazy::new(__abi);
#[rustfmt::skip]
const __BYTECODE: &[u8] = b"`-`7`\x0B\x82\x82\x829\x80Q`\0\x1A`s\x14`*WcNH{q`\xE0\x1B`\0R`\0`\x04R`$`\0\xFD[0`\0R`s\x81S\x82\x81\xF3\xFEs\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x000\x14`\x80`@R`\0\x80\xFD\xFE\xA1dsolcC\0\x08\x17\0\n";
/// The bytecode of the contract.
pub static LIGHTCLIENTSTATEUPDATEVKMOCK_BYTECODE: ::ethers::core::types::Bytes =
::ethers::core::types::Bytes::from_static(__BYTECODE);
#[rustfmt::skip]
const __DEPLOYED_BYTECODE: &[u8] = b"s\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x000\x14`\x80`@R`\0\x80\xFD\xFE\xA1dsolcC\0\x08\x17\0\n";
/// The deployed bytecode of the contract.
pub static LIGHTCLIENTSTATEUPDATEVKMOCK_DEPLOYED_BYTECODE: ::ethers::core::types::Bytes =
::ethers::core::types::Bytes::from_static(__DEPLOYED_BYTECODE);
pub struct LightClientStateUpdateVKMock<M>(::ethers::contract::Contract<M>);
impl<M> ::core::clone::Clone for LightClientStateUpdateVKMock<M> {
fn clone(&self) -> Self {
Self(::core::clone::Clone::clone(&self.0))
}
}
impl<M> ::core::ops::Deref for LightClientStateUpdateVKMock<M> {
type Target = ::ethers::contract::Contract<M>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<M> ::core::ops::DerefMut for LightClientStateUpdateVKMock<M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<M> ::core::fmt::Debug for LightClientStateUpdateVKMock<M> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.debug_tuple(::core::stringify!(LightClientStateUpdateVKMock))
.field(&self.address())
.finish()
}
}
impl<M: ::ethers::providers::Middleware> LightClientStateUpdateVKMock<M> {
/// Creates a new contract instance with the specified `ethers` client at
/// `address`. The contract derefs to a `ethers::Contract` object.
pub fn new<T: Into<::ethers::core::types::Address>>(
address: T,
client: ::std::sync::Arc<M>,
) -> Self {
Self(::ethers::contract::Contract::new(
address.into(),
LIGHTCLIENTSTATEUPDATEVKMOCK_ABI.clone(),
client,
))
}
/// Constructs the general purpose `Deployer` instance based on the provided constructor arguments and sends it.
/// Returns a new instance of a deployer that returns an instance of this contract after sending the transaction
///
/// Notes:
/// - If there are no constructor arguments, you should pass `()` as the argument.
/// - The default poll duration is 7 seconds.
/// - The default number of confirmations is 1 block.
///
///
/// # Example
///
/// Generate contract bindings with `abigen!` and deploy a new contract instance.
///
/// *Note*: this requires a `bytecode` and `abi` object in the `greeter.json` artifact.
///
/// ```ignore
/// # async fn deploy<M: ethers::providers::Middleware>(client: ::std::sync::Arc<M>) {
/// abigen!(Greeter, "../greeter.json");
///
/// let greeter_contract = Greeter::deploy(client, "Hello world!".to_string()).unwrap().send().await.unwrap();
/// let msg = greeter_contract.greet().call().await.unwrap();
/// # }
/// ```
pub fn deploy<T: ::ethers::core::abi::Tokenize>(
client: ::std::sync::Arc<M>,
constructor_args: T,
) -> ::core::result::Result<
::ethers::contract::builders::ContractDeployer<M, Self>,
::ethers::contract::ContractError<M>,
> {
let factory = ::ethers::contract::ContractFactory::new(
LIGHTCLIENTSTATEUPDATEVKMOCK_ABI.clone(),
LIGHTCLIENTSTATEUPDATEVKMOCK_BYTECODE.clone().into(),
client,
);
let deployer = factory.deploy(constructor_args)?;
let deployer = ::ethers::contract::ContractDeployer::new(deployer);
Ok(deployer)
}
}
impl<M: ::ethers::providers::Middleware> From<::ethers::contract::Contract<M>>
for LightClientStateUpdateVKMock<M>
{
fn from(contract: ::ethers::contract::Contract<M>) -> Self {
Self::new(contract.address(), contract.client())
}
}
}
23 changes: 23 additions & 0 deletions contract-bindings/src/shared_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,26 @@ pub struct PlonkProof {
pub sigma_eval_3: ::ethers::core::types::U256,
pub prod_perm_zeta_omega_eval: ::ethers::core::types::U256,
}
///`LightClientState(uint64,uint64,uint256,uint256,uint256,uint256,uint256,uint256)`
#[derive(
Clone,
::ethers::contract::EthAbiType,
::ethers::contract::EthAbiCodec,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
pub struct LightClientState {
pub view_num: u64,
pub block_height: u64,
pub block_comm_root: ::ethers::core::types::U256,
pub fee_ledger_comm: ::ethers::core::types::U256,
pub stake_table_bls_key_comm: ::ethers::core::types::U256,
pub stake_table_schnorr_key_comm: ::ethers::core::types::U256,
pub stake_table_amount_comm: ::ethers::core::types::U256,
pub threshold: ::ethers::core::types::U256,
}
20 changes: 20 additions & 0 deletions contracts/rust/adapter/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ pub struct ParsedLightClientState {
pub threshold: U256,
}

impl ParsedLightClientState {
/// Return a dummy new genesis that will pass constructor/initializer sanity checks
/// in the contract.
///
/// # Warning
/// NEVER use this for production, this is test only.
pub fn dummy_genesis() -> Self {
Self {
view_num: 0,
block_height: 0,
block_comm_root: U256::from(0),
fee_ledger_comm: U256::from(0),
bls_key_comm: U256::from(123),
schnorr_key_comm: U256::from(123),
amount_comm: U256::from(20),
threshold: U256::from(1),
}
}
}

impl FromStr for ParsedLightClientState {
type Err = AbiError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down
2 changes: 1 addition & 1 deletion contracts/rust/gen-vk-contract/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn main() {
powers_of_h: vec![srs.h, srs.beta_h],
}
};
let (_, vk) = hotshot_state_prover::preprocess::<STAKE_TABLE_CAPACITY>(&srs)
let (_, vk) = hotshot_state_prover::preprocess(&srs, STAKE_TABLE_CAPACITY)
.expect("Circuit preprocess failed");
let vk: ParsedVerifyingKey = vk.into();

Expand Down
2 changes: 1 addition & 1 deletion contracts/test/LightClient.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IPlonkVerifier as V } from "../src/interfaces/IPlonkVerifier.sol";

// Target contract
import { LightClient as LC } from "../src/LightClient.sol";
import { LightClientTest as LCTest } from "./mocks/LightClientTest.sol";
import { LightClientMock as LCTest } from "./mocks/LightClientMock.sol";
import { BN254 } from "bn254/BN254.sol";

/// @dev Common helpers for LightClient tests
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/LightClientTest.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import "forge-std/Script.sol";
import { BN254 } from "bn254/BN254.sol";
import { LightClient as LC } from "../src/LightClient.sol";
import { LightClientTest as LCTest } from "../test/mocks/LightClientTest.sol";
import { LightClientMock as LCTest } from "../test/mocks/LightClientMock.sol";

/// @notice deployment script for LightClientTest which is designed for testing purposes with
/// verification key corresponding to smaller circuit, thus faster proof generation during tests.
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/PlonkVerifier.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import { BN254 } from "bn254/BN254.sol";
import { IPlonkVerifier } from "../src/interfaces/IPlonkVerifier.sol";
import { LightClientStateUpdateVKTest as VkTest } from "./mocks/LightClientStateUpdateVKTest.sol";
import { LightClientStateUpdateVKMock as VkTest } from "./mocks/LightClientStateUpdateVKMock.sol";
import { PolynomialEval as Poly } from "../src/libraries/PolynomialEval.sol";

// Target contract
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/StakeTable.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { BLSSig } from "../src/libraries/BLSSig.sol";
import { EdOnBN254 } from "../src/libraries/EdOnBn254.sol";
import { AbstractStakeTable } from "../src/interfaces/AbstractStakeTable.sol";
import { LightClient as LC } from "../src/LightClient.sol";
import { LightClientTest as LCTest } from "../test/mocks/LightClientTest.sol";
import { LightClientMock as LCTest } from "../test/mocks/LightClientMock.sol";

// Token contract
import { ExampleToken } from "../src/ExampleToken.sol";
Expand Down
10 changes: 5 additions & 5 deletions contracts/test/StakeTableInvariant.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { BN254 } from "bn254/BN254.sol";
import { EdOnBN254 } from "../src/libraries/EdOnBn254.sol";
import { AbstractStakeTable } from "../src/interfaces/AbstractStakeTable.sol";
import { LightClient } from "../src/LightClient.sol";
import { LightClientTest } from "../test/mocks/LightClientTest.sol";
import { LightClientMock } from "../test/mocks/LightClientMock.sol";
import { StakeTableCommonTest } from "../test/StakeTable.t.sol";

// Token contract
Expand All @@ -26,7 +26,7 @@ contract StakeTableHandlerTest is StakeTableCommonTest {
ExampleToken public token;
mapping(uint256 index => BN254.G2Point vk) public vks;
BN254.G2Point[] public vksWithdraw;
LightClientTest public lightClient;
LightClientMock public lightClient;
address[] public users;

// Variables for testing invariant relative to Register
Expand All @@ -51,7 +51,7 @@ contract StakeTableHandlerTest is StakeTableCommonTest {
S _stakeTable,
address _tokenCreator,
ExampleToken _token,
LightClientTest _lightClient
LightClientMock _lightClient
) {
stakeTable = _stakeTable;
token = _token;
Expand Down Expand Up @@ -254,7 +254,7 @@ contract StakeTableHandlerTest is StakeTableCommonTest {
contract StakeTableInvariant_Tests is Test {
S public stakeTable;
ExampleToken public token;
LightClientTest public lightClientContract;
LightClientMock public lightClientContract;
uint256 public constant INITIAL_BALANCE = 1_000_000_000_000;
address public exampleTokenCreator;
address[] public users;
Expand All @@ -278,7 +278,7 @@ contract StakeTableInvariant_Tests is Test {
});
uint32 numBlocksPerEpoch = 4;
uint64 churnRate = 10;
lightClientContract = new LightClientTest(genesis, numBlocksPerEpoch);
lightClientContract = new LightClientMock(genesis, numBlocksPerEpoch);
stakeTable = new S(address(token), address(lightClientContract), churnRate);
handler =
new StakeTableHandlerTest(stakeTable, exampleTokenCreator, token, lightClientContract);
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/Transcript.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import { BN254 } from "bn254/BN254.sol";
import { IPlonkVerifier } from "../src/interfaces/IPlonkVerifier.sol";
import { LightClientStateUpdateVKTest as VkTest } from "./mocks/LightClientStateUpdateVKTest.sol";
import { LightClientStateUpdateVKMock as VkTest } from "./mocks/LightClientStateUpdateVKMock.sol";

// Target contract
import { Transcript as T } from "../src/libraries/Transcript.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ pragma solidity ^0.8.0;
import { LightClient as LC } from "../../src/LightClient.sol";
import { IPlonkVerifier } from "../../src/interfaces/IPlonkVerifier.sol";
import { PlonkVerifier } from "../../src/libraries/PlonkVerifier.sol";
import { LightClientStateUpdateVKTest as VkLib } from "./LightClientStateUpdateVKTest.sol";
import { LightClientStateUpdateVKMock as VkLib } from "./LightClientStateUpdateVKMock.sol";

/// @dev A helper that wraps LightClient contract for testing
contract LightClientTest is LC {
contract LightClientMock is LC {
constructor(LC.LightClientState memory genesis, uint32 numBlockPerEpoch) LC() {
_initializeState(genesis, numBlockPerEpoch);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { IPlonkVerifier } from "../../src/interfaces/IPlonkVerifier.sol";

/* solhint-disable no-inline-assembly */

library LightClientStateUpdateVKTest {
library LightClientStateUpdateVKMock {
function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {
assembly {
// domain size
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ services:
image: ghcr.io/espressosystems/espresso-sequencer/sequencer:main
ports:
- "$ESPRESSO_SEQUENCER1_API_PORT:$ESPRESSO_SEQUENCER_API_PORT"
command: sequencer -- storage-sql -- http -- query -- catchup
command: sequencer -- storage-sql -- http -- query -- catchup -- state
environment:
- ESPRESSO_SEQUENCER_ORCHESTRATOR_URL
- ESPRESSO_SEQUENCER_CDN_ENDPOINT
Expand Down Expand Up @@ -417,6 +417,7 @@ services:

sequencer-db:
image: postgres
user: postgres
ports:
- "$ESPRESSO_SEQUENCER_DB_PORT:5432"
environment:
Expand Down
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
description = "Spell checking";
entry = "typos";
pass_filenames = true;
excludes = [ "contract-bindings/artifacts" ];
excludes = [ "contract-bindings/" ];
};
nixpkgs-fmt.enable = true;
};
Expand Down
5 changes: 4 additions & 1 deletion hotshot-state-prover/src/bin/gen-demo-genesis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::Parser;
use ethers::abi::AbiEncode;
use hotshot_stake_table::config::STAKE_TABLE_CAPACITY;
use hotshot_state_prover::service::light_client_genesis;
use url::Url;

Expand All @@ -18,6 +19,8 @@ struct Args {
#[async_std::main]
async fn main() {
let args = Args::parse();
let pi = light_client_genesis(&args.orchestrator_url).await.unwrap();
let pi = light_client_genesis(&args.orchestrator_url, STAKE_TABLE_CAPACITY)
.await
.unwrap();
println!("{}", pi.encode_hex());
}
Loading
Loading