Skip to content
This repository has been archived by the owner on Nov 29, 2024. It is now read-only.

Commit

Permalink
imp(operator): allow custom 'trust_level' (#67)
Browse files Browse the repository at this point in the history
* imp: updated genesis cli

* imp: added custom trust level to fixtures

* test: improved e2e

* test: updated solidity tests and scripts
  • Loading branch information
srdtrk authored Jul 17, 2024
1 parent b04ce6e commit 18b36e9
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 62 deletions.
9 changes: 4 additions & 5 deletions contracts/script/SP1ICS07Tendermint.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ contract SP1TendermintScript is Script {

ICS07Tendermint.ClientState memory clientState = ics07Tendermint
.getClientState();
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);
assert(
keccak256(abi.encode(clientState)) ==
keccak256(genesis.trustedClientState)
);

bytes32 consensusHash = ics07Tendermint.getConsensusStateHash(
clientState.latest_height.revision_height
Expand Down
10 changes: 2 additions & 8 deletions contracts/test/SP1ICS07TendermintTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,9 @@ abstract contract SP1ICS07TendermintTest is Test {
ICS07Tendermint.ClientState memory clientState = mockIcs07Tendermint
.getClientState();
assert(
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
keccak256(abi.encode(clientState)) ==
keccak256(mockGenesisFixture.trustedClientState)
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = mockIcs07Tendermint.getConsensusStateHash(
clientState.latest_height.revision_height
Expand Down
19 changes: 0 additions & 19 deletions contracts/test/UcAndMembership.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,9 @@ contract SP1ICS07UpdateClientAndMembershipTest is SP1ICS07TendermintTest {

ICS07Tendermint.ClientState memory clientState = ics07Tendermint
.getClientState();
assert(
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(
clientState.latest_height.revision_height == fixture.targetHeight
);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = ics07Tendermint.getConsensusStateHash(
Expand Down Expand Up @@ -158,14 +149,9 @@ contract SP1ICS07UpdateClientAndMembershipTest is SP1ICS07TendermintTest {
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(
clientState.latest_height.revision_height == fixture.targetHeight
);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = mockIcs07Tendermint.getConsensusStateHash(
Expand Down Expand Up @@ -210,14 +196,9 @@ contract SP1ICS07UpdateClientAndMembershipTest is SP1ICS07TendermintTest {
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(
clientState.latest_height.revision_height == fixture.targetHeight
);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = ics07Tendermint.getConsensusStateHash(
Expand Down
14 changes: 0 additions & 14 deletions contracts/test/UpdateClient.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,9 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest {
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(
clientState.latest_height.revision_height == fixture.targetHeight
);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = ics07Tendermint.getConsensusStateHash(
Expand Down Expand Up @@ -169,19 +164,10 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest {
assert(res == UpdateClientProgram.UpdateResult.Update);
ICS07Tendermint.ClientState memory clientState = mockIcs07Tendermint
.getClientState();
assert(
keccak256(bytes(clientState.chain_id)) ==
keccak256(bytes("mocha-4"))
);
assert(clientState.trust_level.numerator == 1);
assert(clientState.trust_level.denominator == 3);
assert(clientState.latest_height.revision_number == 4);
assert(
clientState.latest_height.revision_height ==
mockFixture.targetHeight
);
assert(clientState.trusting_period == 1_209_600);
assert(clientState.unbonding_period == 1_209_600);
assert(clientState.is_frozen == false);

bytes32 consensusHash = mockIcs07Tendermint.getConsensusStateHash(
Expand Down
10 changes: 5 additions & 5 deletions e2e/interchaintestv8/sp1_ics07_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context) {
}))

s.Require().True(s.Run("Deploy contracts", func() {
s.Require().NoError(operator.RunGenesis())
s.Require().NoError(operator.RunGenesis("--trust-level", testvalues.DefaultTrustLevel.String()))

stdout, _, err := eth.ForgeScript(ctx, s.UserA.KeyName(), ethereum.ForgeScriptOpts{
ContractRootDir: "contracts",
Expand Down Expand Up @@ -108,8 +108,8 @@ func (s *SP1ICS07TendermintTestSuite) TestDeploy() {
s.Require().NoError(err)

s.Require().Equal(simd.Config().ChainID, clientState.ChainId)
s.Require().Equal(uint8(1), clientState.TrustLevel.Numerator)
s.Require().Equal(uint8(3), clientState.TrustLevel.Denominator)
s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator)
s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator)
s.Require().Equal(uint32(1_209_600), clientState.TrustingPeriod)
s.Require().Equal(uint32(1_209_600), clientState.UnbondingPeriod)
s.Require().False(clientState.IsFrozen)
Expand All @@ -135,8 +135,8 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient() {
s.Require().NoError(err)

s.Require().Equal(simd.Config().ChainID, clientState.ChainId)
s.Require().Equal(uint8(1), clientState.TrustLevel.Numerator)
s.Require().Equal(uint8(3), clientState.TrustLevel.Denominator)
s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator)
s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator)
s.Require().Equal(uint32(1_209_600), clientState.TrustingPeriod)
s.Require().Equal(uint32(1_209_600), clientState.UnbondingPeriod)
s.Require().False(clientState.IsFrozen)
Expand Down
5 changes: 5 additions & 0 deletions e2e/interchaintestv8/testvalues/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"cosmossdk.io/math"

ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"

"github.com/strangelove-ventures/interchaintest/v8/chain/ethereum"
)

Expand Down Expand Up @@ -36,4 +38,7 @@ var (

// StartingEthBalance is the amount of ETH to give to each user at the start of the test.
StartingEthBalance = math.NewInt(2 * ethereum.ETHER)

// DefaultTrustLevel is the trust level used by the SP1ICS07Tendermint contract.
DefaultTrustLevel = ibctm.Fraction{Numerator: 2, Denominator: 3}.ToTendermint()
)
Binary file modified elf/membership-riscv32im-succinct-zkvm-elf
Binary file not shown.
Binary file modified elf/uc-and-membership-riscv32im-succinct-zkvm-elf
Binary file not shown.
Binary file modified elf/update-client-riscv32im-succinct-zkvm-elf
Binary file not shown.
54 changes: 53 additions & 1 deletion operator/src/cli/command.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Contains the command line interface for the application.
use clap::{command, Parser};
use tendermint_light_client_verifier::types::TrustThreshold;

/// The command line interface for the operator.
#[derive(Clone, Debug, Parser)]
Expand Down Expand Up @@ -29,12 +30,20 @@ pub mod genesis {
/// The arguments for the `genesis` executable.
#[derive(Parser, Debug, Clone)]
pub struct Args {
/// Trusted block.
/// Trusted block height. [default: latest]
#[clap(long)]
pub trusted_block: Option<u32>,
/// Genesis path.
#[clap(long, default_value = "../contracts/script")]
pub genesis_path: String,
/// Trust level.
#[clap(
long,
default_value = "1/3",
value_parser = super::parse_trust_threshold,
help = "Trust level as a fraction, e.g. '2/3'",
)]
pub trust_level: super::TrustThreshold,
}
}

Expand Down Expand Up @@ -89,6 +98,15 @@ pub mod fixtures {
/// Fixture path.
#[clap(long, short = 'o')]
pub output_path: String,

/// Trust level.
#[clap(
long,
default_value = "1/3",
value_parser = super::parse_trust_threshold,
help = "Trust level as a fraction, e.g. '2/3'",
)]
pub trust_level: super::TrustThreshold,
}

/// The arguments for the `Membership` fixture executable.
Expand All @@ -106,6 +124,15 @@ pub mod fixtures {
/// Fixture path.
#[clap(long, short = 'o')]
pub output_path: String,

/// Trust level.
#[clap(
long,
default_value = "1/3",
value_parser = super::parse_trust_threshold,
help = "Trust level as a fraction, e.g. '2/3'",
)]
pub trust_level: super::TrustThreshold,
}

/// The arguments for the `UpdateClientAndMembership` fixture executable.
Expand All @@ -127,5 +154,30 @@ pub mod fixtures {
/// Fixture path.
#[clap(long, short = 'o')]
pub output_path: String,

/// Trust level.
#[clap(
long,
default_value = "1/3",
value_parser = super::parse_trust_threshold,
help = "Trust level as a fraction, e.g. '2/3'",
)]
pub trust_level: super::TrustThreshold,
}
}

fn parse_trust_threshold(input: &str) -> anyhow::Result<TrustThreshold> {
let (num_part, denom_part) = input.split_once('/').ok_or_else(|| {
anyhow::anyhow!("invalid trust threshold fraction: expected format 'numerator/denominator'")
})?;
let numerator = num_part
.trim()
.parse()
.map_err(|_| anyhow::anyhow!("invalid numerator for the fraction"))?;
let denominator = denom_part
.trim()
.parse()
.map_err(|_| anyhow::anyhow!("invalid denominator for the fraction"))?;
TrustThreshold::new(numerator, denominator)
.map_err(|e| anyhow::anyhow!("invalid trust threshold: {}", e))
}
9 changes: 3 additions & 6 deletions operator/src/helpers/light_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub trait LightBlockExt {
///
/// # Errors
/// Returns an error if the chain identifier or height cannot be parsed.
fn to_sol_client_state(&self) -> anyhow::Result<ClientState>;
fn to_sol_client_state(&self, trust_level: TrustThreshold) -> anyhow::Result<ClientState>;
/// Convert the [`LightBlock`] to a new [`ConsensusState`].
#[must_use]
fn to_consensus_state(&self) -> ConsensusState;
Expand All @@ -34,15 +34,12 @@ pub trait LightBlockExt {
}

impl LightBlockExt for LightBlock {
fn to_sol_client_state(&self) -> anyhow::Result<ClientState> {
fn to_sol_client_state(&self, trust_level: TrustThreshold) -> anyhow::Result<ClientState> {
let chain_id = ChainId::from_str(self.signed_header.header.chain_id.as_str())?;
let two_weeks_in_seconds = 14 * 24 * 60 * 60;
Ok(ClientState {
chain_id: chain_id.to_string(),
trust_level: TrustThreshold {
numerator: 1,
denominator: 3,
},
trust_level,
latest_height: Height {
revision_number: chain_id.revision_number().try_into()?,
revision_height: self.height().value().try_into()?,
Expand Down
3 changes: 2 additions & 1 deletion operator/src/runners/fixtures/membership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub async fn run(args: MembershipCmd) -> anyhow::Result<()> {
.get_light_block(Some(args.trusted_block))
.await?;

let trusted_client_state = trusted_light_block.to_sol_client_state()?;
let trusted_client_state =
trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?;
let trusted_consensus_state = trusted_light_block.to_consensus_state();
let commitment_root_bytes = trusted_consensus_state.root.as_bytes().to_vec();

Expand Down
3 changes: 2 additions & 1 deletion operator/src/runners/fixtures/uc_and_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ pub async fn run(args: UpdateClientAndMembershipCmd) -> anyhow::Result<()> {
.get_light_block(Some(args.target_block))
.await?;

let trusted_client_state = trusted_light_block.to_sol_client_state()?;
let trusted_client_state =
trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?;
let trusted_consensus_state = trusted_light_block.to_consensus_state().into();
let proposed_header = target_light_block.into_header(&trusted_light_block);
let contract_env = Env {
Expand Down
3 changes: 2 additions & 1 deletion operator/src/runners/fixtures/update_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub async fn run(args: UpdateClientCmd) -> anyhow::Result<()> {
.get_light_block(Some(args.target_block))
.await?;

let trusted_client_state = trusted_light_block.to_sol_client_state()?;
let trusted_client_state =
trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?;
let trusted_consensus_state = trusted_light_block.to_consensus_state().into();
let proposed_header = target_light_block.into_header(&trusted_light_block);
let contract_env = Env {
Expand Down
3 changes: 2 additions & 1 deletion operator/src/runners/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ pub async fn run(args: Args) -> anyhow::Result<()> {
);
}

let trusted_client_state = trusted_light_block.to_sol_client_state()?;
let trusted_client_state =
trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?;
let trusted_consensus_state = trusted_light_block.to_consensus_state();
let genesis = SP1ICS07TendermintGenesis {
trusted_consensus_state: hex::encode(
Expand Down
11 changes: 11 additions & 0 deletions packages/solidity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ impl From<sp1_ics07_tendermint::TrustThreshold> for TendermintTrustThreshold {
}
}

impl TryFrom<TendermintTrustThreshold> for sp1_ics07_tendermint::TrustThreshold {
type Error = <u64 as TryInto<u32>>::Error;

fn try_from(trust_threshold: TendermintTrustThreshold) -> Result<Self, Self::Error> {
Ok(Self {
numerator: trust_threshold.numerator().try_into()?,
denominator: trust_threshold.denominator().try_into()?,
})
}
}

#[allow(clippy::fallible_impl_from)]
impl From<ICS07TendermintConsensusState> for sp1_ics07_tendermint::ConsensusState {
fn from(ics07_tendermint_consensus_state: ICS07TendermintConsensusState) -> Self {
Expand Down

0 comments on commit 18b36e9

Please sign in to comment.