Skip to content

Commit

Permalink
feat(move): remaining fixes for movement testnet integration
Browse files Browse the repository at this point in the history
Signed-off-by: aeryz <[email protected]>
  • Loading branch information
aeryz committed Oct 1, 2024
1 parent 70b6c7c commit b9b6e37
Show file tree
Hide file tree
Showing 14 changed files with 329 additions and 281 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ fbef3d1a-8b84-4eb5-937c-06f78b1a1347
db.sqlite
db.sqlite3*

*/.movement
*.movement
move/*/build
.tsup
docs/generated
Expand Down
4 changes: 2 additions & 2 deletions lib/unionlabs/src/aptos/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{bls::BlsSignature, errors::InvalidLength};
from
))]
pub struct AggregateSignature {
validator_bitmask: ValidatorBitmask,
sig: Option<BlsSignature>,
pub validator_bitmask: ValidatorBitmask,
pub sig: Option<BlsSignature>,
}

#[model]
Expand Down
37 changes: 36 additions & 1 deletion lib/unionlabs/src/aptos/state_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ use macros::model;
use sha2::Digest;

use super::{
block_info::BlockInfo,
epoch_change::{EpochChangeProof, TryFromEpochChangeProof},
ledger_info::{LedgerInfo, LedgerInfoWithSignatures, TryFromLedgerInfoWithSignatures},
signature::AggregateSignature,
};
use crate::{
errors::{required, MissingField},
hash::hash_v2::Hash,
};
use crate::errors::{required, MissingField};

/// A convenience type for the collection of sub-proofs that constitute a
/// response to a `get_state_proof` request.
Expand All @@ -28,6 +33,36 @@ pub struct StateProof {
pub epoch_changes: EpochChangeProof,
}

// TODO(aeryz): only for testing purposes, will remove this once we have state proofs
impl Default for StateProof {
fn default() -> Self {
Self {
latest_li_w_sigs: LedgerInfoWithSignatures::V0(super::ledger_info::LedgerInfoWithV0 {
ledger_info: LedgerInfo {
commit_info: BlockInfo {
epoch: 0,
round: 0,
id: Hash::default(),
executed_state_id: Hash::default(),
version: 0,
timestamp_usecs: 0,
next_epoch_state: None,
},
consensus_data_hash: Hash::default(),
},
signatures: AggregateSignature {
validator_bitmask: super::signature::ValidatorBitmask { inner: vec![] },
sig: None,
},
}),
epoch_changes: EpochChangeProof {
ledger_info_with_sigs: vec![],
more: false,
},
}
}
}

impl StateProof {
#[must_use]
pub fn new(
Expand Down
26 changes: 25 additions & 1 deletion lib/unionlabs/src/aptos/transaction_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use macros::model;
use crate::{
aptos::transaction_info::{TransactionInfo, TryFromTransactionInfoError},
errors::{required, InvalidLength, MissingField},
hash::{hash_v2::HexUnprefixed, H256},
hash::{
hash_v2::{Hash, HexUnprefixed},
H256,
},
};

/// `TransactionInfo` and a `TransactionAccumulatorProof` connecting it to the ledger root.
Expand All @@ -21,6 +24,27 @@ pub struct TransactionInfoWithProof {
pub transaction_info: TransactionInfo,
}

// TODO(aeryz): only for testing purposes until we have proper proofs
impl Default for TransactionInfoWithProof {
fn default() -> Self {
Self {
ledger_info_to_transaction_info_proof: TransactionAccumulatorProof {
siblings: vec![],
phantom: Null,
},
transaction_info: TransactionInfo::V0(super::transaction_info::TransactionInfoV0 {
gas_used: 0,
status: super::transaction_info::ExecutionStatus::Success,
transaction_hash: Hash::default(),
event_root_hash: Hash::default(),
state_change_hash: Hash::default(),
state_checkpoint_hash: Some(Hash::default()),
state_cemetery_hash: None,
}),
}
}
}

#[model]
pub struct TransactionAccumulatorProof {
pub siblings: Vec<H256<HexUnprefixed>>,
Expand Down
3 changes: 3 additions & 0 deletions light-clients/movement/ics08-movement/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ workspace = true

[lib]
crate-type = ["cdylib", "rlib"]

[features]
union-movement = []
142 changes: 76 additions & 66 deletions light-clients/movement/ics08-movement/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,79 +66,89 @@ impl IbcClient for MovementLightClient {
mut path: MerklePath,
value: StorageState,
) -> Result<(), IbcClientError<Self>> {
let consensus_state: WasmConsensusState =
read_consensus_state(deps, &height)?.ok_or(Error::ConsensusStateNotFound(height))?;
let client_state: WasmClientState = read_client_state(deps)?;

let path = path.key_path.pop().ok_or(Error::EmptyIbcPath)?;

match value {
StorageState::Occupied(value) => do_verify_membership(
path,
consensus_state.data.state_root,
client_state.data.table_handle,
proof,
value,
),
StorageState::Empty => unimplemented!(),
#[cfg(feature = "union-movement")]
{
let consensus_state: WasmConsensusState = read_consensus_state(deps, &height)?
.ok_or(Error::ConsensusStateNotFound(height))?;
let client_state: WasmClientState = read_client_state(deps)?;

let path = path.key_path.pop().ok_or(Error::EmptyIbcPath)?;

match value {
StorageState::Occupied(value) => do_verify_membership(
path,
consensus_state.data.state_root,
client_state.data.table_handle,
proof,
value,
)?,
StorageState::Empty => unimplemented!(),
}
}
Ok(())
}

fn verify_header(
_deps: Deps<Self::CustomQuery>,
_env: cosmwasm_std::Env,
deps: Deps<Self::CustomQuery>,
env: cosmwasm_std::Env,
header: Header,
) -> Result<(), IbcClientError<Self>> {
aptos_verifier::verify_tx_state(
&header.tx_proof,
*header
.state_proof
.latest_ledger_info()
.commit_info
.executed_state_id
.get(),
header.tx_index,
)
.map_err(Into::<Error>::into)?;

// TODO(aeryz): make sure the given state_proof_hash_proof.key matches the correct slot

// NOTE(aeryz): FOR AUDITORS and NERDS:
// Movement is currently using an internal eth node to settle on, which we don't have access to get the proofs.
// Hence, the following checks are disabled and the client is made permissioned until we have access to the proofs.

// let client_state: WasmClientState = read_client_state(deps)?;

// let l1_consensus_state = query_consensus_state::<WasmL1ConsensusState>(
// deps,
// &env,
// client_state.data.l1_client_id.to_string(),
// header.l1_height,
// )
// .map_err(Error::CustomQuery)?;

// let expected_commitment = BlockCommitment {
// height: header.new_height.into(),
// commitment: U256::from_be_bytes(header.state_proof.hash()),
// block_id: U256::from_be_bytes(header.state_proof.latest_ledger_info().commit_info.id.0),
// };

// ethereum_verifier::verify::verify_account_storage_root(
// l1_consensus_state.data.state_root,
// &client_state.data.l1_contract_address,
// &header.settlement_contract_proof.proof,
// &header.settlement_contract_proof.storage_root,
// )
// .unwrap();

// ethereum_verifier::verify::verify_storage_proof(
// header.settlement_contract_proof.storage_root,
// header.state_proof_hash_proof.key,
// &rlp::encode(&expected_commitment),
// header.state_proof_hash_proof.proof,
// )
// .unwrap();

// Movement's current REST API's don't provide state and transaction proofs. We added those to our custom
// Movement node which we also work on getting them to be upstreamed. Hence, we use the following feature-flag with
// a custom setup.
// Also see the related PR: https://github.com/movementlabsxyz/movement/pull/645

#[cfg(feature = "union-movement")]
{
aptos_verifier::verify_tx_state(
&header.tx_proof,
*header
.state_proof
.latest_ledger_info()
.commit_info
.executed_state_id
.get(),
header.tx_index,
)
.map_err(Into::<Error>::into)?;

// TODO(aeryz): make sure the given state_proof_hash_proof.key matches the correct slot

let client_state: WasmClientState = read_client_state(deps)?;

let l1_consensus_state = query_consensus_state::<WasmL1ConsensusState>(
deps,
&env,
client_state.data.l1_client_id.to_string(),
header.l1_height,
)
.map_err(Error::CustomQuery)?;

let expected_commitment = BlockCommitment {
height: header.new_height.into(),
commitment: U256::from_be_bytes(header.state_proof.hash()),
block_id: U256::from_be_bytes(
header.state_proof.latest_ledger_info().commit_info.id.0,
),
};

ethereum_verifier::verify::verify_account_storage_root(
l1_consensus_state.data.state_root,
&client_state.data.l1_contract_address,
&header.settlement_contract_proof.proof,
&header.settlement_contract_proof.storage_root,
)
.unwrap();

ethereum_verifier::verify::verify_storage_proof(
header.settlement_contract_proof.storage_root,
header.state_proof_hash_proof.key,
&rlp::encode(&expected_commitment),
header.state_proof_hash_proof.proof,
)
.unwrap();
}
Ok(())
}

Expand Down
6 changes: 4 additions & 2 deletions move/move-ibc/sources/cometbls_light_client.move
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ module IBC::LightClient {

assert!(
height::get_revision_height(&client_state.latest_height) != 0 &&
consensus_state.timestamp == 0, E_INVALID_CLIENT_STATE
consensus_state.timestamp != 0, E_INVALID_CLIENT_STATE
);

assert!(string::length(&client_state.chain_id) <= 31, E_INVALID_CLIENT_STATE);
Expand Down Expand Up @@ -197,7 +197,9 @@ module IBC::LightClient {
prefix,
path,
value
)
);

0
}

public fun verify_non_membership(
Expand Down
6 changes: 6 additions & 0 deletions move/move-ibc/sources/height.move
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ module IBC::height {
height1.revision_height >= height2.revision_height)
}

public fun lt(height1: &Height, height2: &Height): bool {
height1.revision_number < height2.revision_number ||
(height1.revision_number == height2.revision_number &&
height1.revision_height < height2.revision_height)
}

public fun set_revision_height(height: &mut Height, revision_height: u64) {
height.revision_height = revision_height;
}
Expand Down
Loading

0 comments on commit b9b6e37

Please sign in to comment.