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

Movement temporary trusted verification #3948

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

43 changes: 32 additions & 11 deletions cosmwasm/ibc-union/lightclient/movement/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use movement_light_client_types::{
};
use unionlabs::{
aptos::{
account::AccountAddress, storage_proof::StorageProof, transaction_info::TransactionInfo,
account::AccountAddress, signed_data::SignedData, storage_proof::StorageProof,
transaction_info::TransactionInfo,
},
encoding::Bincode,
primitives::{H256, U256},
Expand All @@ -28,25 +29,38 @@ impl IbcClient for MovementLightClient {

type CustomQuery = Empty;

type Header = Header;
type Header = SignedData<Header>;

type Misbehaviour = Header;

type ClientState = ClientState;

type ConsensusState = ConsensusState;

type StorageProof = StorageProof;
type StorageProof = SignedData<StorageProof>;

type Encoding = Bincode;

fn verify_membership(
_ctx: IbcClientCtx<Self>,
ctx: IbcClientCtx<Self>,
_height: u64,
_key: Vec<u8>,
_storage_proof: Self::StorageProof,
storage_proof: Self::StorageProof,
_value: Vec<u8>,
) -> Result<(), IbcClientError<Self>> {
let client_state = ctx.read_self_client_state()?;
if !ctx
.deps
.api
.ed25519_verify(
&storage_proof.hash(),
storage_proof.signature.as_ref(),
client_state.auth_pubkey.as_ref(),
)
.map_err(Into::<Error>::into)?
{
return Err(Error::AuthenticationFailure.into());
}
// let client_state = ctx.read_self_client_state()?;
// let consensus_state = ctx.read_self_consensus_state(height)?;
// verify_membership(
Expand Down Expand Up @@ -101,15 +115,22 @@ impl IbcClient for MovementLightClient {
fn verify_header(
ctx: IbcClientCtx<Self>,
header: Self::Header,
caller: cosmwasm_std::Addr,
_caller: cosmwasm_std::Addr,
) -> Result<(u64, Self::ClientState, Self::ConsensusState), IbcClientError<Self>> {
let client_state = ctx.read_self_client_state()?;
// Check if caller is whitelisted
if !client_state
.whitelisted_relayers
.contains(&caller.to_string())

if !ctx
.deps
.api
.ed25519_verify(
&header.hash(),
header.signature.as_ref(),
client_state.auth_pubkey.as_ref(),
)
.map_err(Into::<Error>::into)?
{
return Err(IbcClientError::UnauthorizedCaller(caller.to_string()));
return Err(Error::AuthenticationFailure.into());
}

// NOTE(aeryz): FOR AUDITORS and NERDS:
Expand Down Expand Up @@ -167,7 +188,7 @@ impl IbcClient for MovementLightClient {
)
.unwrap();
}
update_state(client_state, header).map_err(Into::into)
update_state(client_state, header.data).map_err(Into::into)
}

fn misbehaviour(
Expand Down
6 changes: 5 additions & 1 deletion cosmwasm/ibc-union/lightclient/movement/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmwasm_std::StdError;
use cosmwasm_std::{StdError, VerificationError};
use ibc_union_light_client::IbcClientError;
use unionlabs::ibc::core::client::height::Height;

Expand Down Expand Up @@ -26,6 +26,10 @@ pub enum Error {
InvalidIbcPath(String),
#[error(transparent)]
StdError(#[from] StdError),
#[error("authentication failure")]
AuthenticationFailure,
#[error(transparent)]
VerificationError(#[from] VerificationError),
}

impl From<Error> for StdError {
Expand Down
6 changes: 4 additions & 2 deletions lib/movement-light-client-types/src/client_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use unionlabs::{
aptos::account::AccountAddress, ibc::core::client::height::Height, primitives::H160,
aptos::account::AccountAddress,
ibc::core::client::height::Height,
primitives::{H160, H256},
};

#[derive(Debug, Clone, PartialEq)]
Expand All @@ -13,5 +15,5 @@ pub struct ClientState {
pub table_handle: AccountAddress,
pub frozen_height: Height,
pub latest_block_num: u64,
pub whitelisted_relayers: Vec<String>,
pub auth_pubkey: H256,
}
1 change: 1 addition & 0 deletions lib/unionlabs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ schemars = { workspace = true, features = ["derive"], optional = tru
serde_bytes = "0.11.6"
unionlabs-primitives = { workspace = true, features = ["generic-array-compat", "serde", "base64"] }


[dev-dependencies]
rand = "0.8.5"
serde_json = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions lib/unionlabs/src/aptos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub mod ledger_info;
pub mod object;
pub mod public_key;
pub mod signature;
#[cfg(feature = "bincode")]
pub mod signed_data;
pub mod sparse_merkle_proof;
pub mod state_proof;
pub mod storage_proof;
Expand Down
25 changes: 25 additions & 0 deletions lib/unionlabs/src/aptos/signed_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use macros::model;
use sha2::Digest;
use unionlabs_primitives::H512;

use crate::encoding::{Bincode, Encode};

#[model]
#[derive(bincode::Encode, bincode::Decode)]
pub struct SignedData<T> {
pub signature: H512,
pub data: T,
}

impl<T: Encode<Bincode> + Clone> SignedData<T> {
pub fn hash(&self) -> Vec<u8> {
hash_signature_data(self.data.clone())
}
}

pub fn hash_signature_data<T: Encode<Bincode> + Clone>(data: T) -> Vec<u8> {
sha2::Sha256::new()
.chain_update(data.encode())
.finalize()
.to_vec()
}
21 changes: 5 additions & 16 deletions voyager/modules/client-bootstrap/movement/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use unionlabs::{
transaction_proof::TransactionInfoWithProof,
},
ibc::core::client::height::Height,
primitives::{FixedBytes, H160, U256},
primitives::{FixedBytes, H160, H256, U256},
};
use voyager_message::{
core::{ChainId, ClientType},
Expand Down Expand Up @@ -52,7 +52,7 @@ pub struct Module {

pub movement_rest_url: String,

pub whitelisted_relayers: Vec<String>,
pub auth_pubkey: H256,
}

impl ClientBootstrapModule for Module {
Expand All @@ -76,11 +76,7 @@ impl ClientBootstrapModule for Module {
l1_settlement_address: config.l1_settlement_address,
l1_client_id: config.l1_client_id,
movement_rest_url: config.movement_rest_url,
whitelisted_relayers: config
.whitelisted_relayers
.into_iter()
.map(Into::into)
.collect(),
auth_pubkey: config.auth_pubkey,
})
}
}
Expand Down Expand Up @@ -109,14 +105,7 @@ pub struct Config {
/// The RPC endpoint for custom movement apis.
pub movement_rest_url: String,

/// The relayers that are allowed to modify this light client
///
/// Note that the light client had to be permissioned for now since
/// we are waiting for our [PR] to be merged so that we can fetch
/// the necessary proofs.
///
/// [PR]: https://github.com/movementlabsxyz/movement/pull/645
pub whitelisted_relayers: Vec<cosmwasm_std::Addr>,
pub auth_pubkey: H256,
}

impl Module {
Expand Down Expand Up @@ -190,7 +179,7 @@ impl ClientBootstrapModuleServer for Module {
)),
frozen_height: Height::new(0),
latest_block_num: height.height(),
whitelisted_relayers: self.whitelisted_relayers.clone(),
auth_pubkey: self.auth_pubkey,
})
.expect("infallible"))
}
Expand Down
1 change: 1 addition & 0 deletions voyager/modules/proof/movement/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ aptos-move-ibc = { workspace = true }
aptos-rest-client = { workspace = true }
aptos-types = { workspace = true }
clap = { workspace = true, features = ["derive"] }
ed25519-zebra = { version = "4.0" }
ibc-union-spec = { workspace = true }
jsonrpsee = { workspace = true, features = ["macros", "server", "tracing"] }
reqwest = { workspace = true, features = ["json"] }
Expand Down
30 changes: 22 additions & 8 deletions voyager/modules/proof/movement/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt::Debug;
use aptos_move_ibc::ibc::ClientExt as _;
use aptos_rest_client::{aptos_api_types::Address, error::RestError};
use aptos_types::state_store::state_value::PersistedStateValueMetadata;
use ed25519_zebra::SigningKey;
use ibc_union_spec::{path::StorePath, IbcUnion};
use jsonrpsee::{
core::{async_trait, RpcResult},
Expand All @@ -14,11 +15,12 @@ use serde_json::Value;
use tracing::{debug, instrument};
use unionlabs::{
aptos::{
signed_data::{hash_signature_data, SignedData},
sparse_merkle_proof::{SparseMerkleLeafNode, SparseMerkleProof},
storage_proof::{StateValue, StateValueMetadata, StorageProof},
},
ibc::core::client::height::Height,
primitives::{H256, U256},
primitives::{H256, H512, U256},
ErrorReporter,
};
use voyager_message::{
Expand Down Expand Up @@ -51,6 +53,8 @@ pub struct Module {
pub movement_rpc_url: String,

pub ibc_handler_address: Address,

pub auth_signing_key: SigningKey,
}

impl ProofModule<IbcUnion> for Module {
Expand All @@ -68,6 +72,7 @@ impl ProofModule<IbcUnion> for Module {
aptos_client,
movement_rpc_url: config.movement_rpc_url,
ibc_handler_address: config.ibc_handler_address,
auth_signing_key: SigningKey::from(*config.auth_private_key.get()),
})
}
}
Expand All @@ -78,6 +83,7 @@ pub struct Config {
pub rpc_url: String,
pub movement_rpc_url: String,
pub ibc_handler_address: Address,
pub auth_private_key: H256,
}

impl aptos_move_ibc::ibc::ClientExt for Module {
Expand Down Expand Up @@ -151,14 +157,22 @@ impl ProofModuleServer<IbcUnion> for Module {
// at.revision_height,
// ).await;

let proof = StorageProof {
state_value: None,
proof: SparseMerkleProof {
leaf: None,
siblings: Vec::new(),
},
};
let signed_data = self
.auth_signing_key
.sign(&hash_signature_data(proof.clone()));
let signed_proof = SignedData {
signature: H512::new(signed_data.to_bytes()),
data: proof,
};
Ok((
into_value(StorageProof {
state_value: None,
proof: SparseMerkleProof {
leaf: None,
siblings: Vec::new(),
},
}),
into_value(signed_proof),
// TODO: Implement properly, see above
ProofType::Membership,
))
Expand Down
1 change: 1 addition & 0 deletions voyager/plugins/client-update/movement/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ workspace = true
[dependencies]
aptos-move-ibc = { workspace = true }
aptos-rest-client = { workspace = true }
ed25519-zebra = { version = "4.0" }
enumorph = { workspace = true }
ethereum-light-client-types = { workspace = true }
jsonrpsee = { workspace = true, features = ["macros", "server", "tracing"] }
Expand Down
Loading