Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into wasm-backend
Browse files Browse the repository at this point in the history
  • Loading branch information
codabrink committed Oct 16, 2024
2 parents fe27ed1 + 6937f23 commit 94f82b6
Show file tree
Hide file tree
Showing 16 changed files with 5,657 additions and 64 deletions.
5,434 changes: 5,434 additions & 0 deletions bindings_wasm/Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dev/build_validation_service_local
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ set -eu
if [ ! -x "$(command -v x86_64-linux-gnu-gcc)" ] && [ "$(uname)" = "Darwin" ]; then
echo "Installing cross compile toolchain"
brew tap messense/macos-cross-toolchains
brew install x86_64-unknown-linux-gnu
brew install x86_64-unknown-linux-gnu
fi

rustup target add x86_64-unknown-linux-gnu
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc
cargo build --release --package mls_validation_service --target x86_64-unknown-linux-gnu
cargo build --release --package mls_validation_service --features test-utils --target x86_64-unknown-linux-gnu
mkdir -p .cache
cp -f ./target/x86_64-unknown-linux-gnu/release/mls-validation-service ./.cache/mls-validation-service
docker build --platform=linux/amd64 -t xmtp/mls-validation-service:latest -f ./dev/validation_service/local.Dockerfile .
6 changes: 6 additions & 0 deletions dev/docker/anvil.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# syntax=docker/dockerfile:1.4
FROM ghcr.io/foundry-rs/foundry

WORKDIR /anvil

ENTRYPOINT anvil --host 0.0.0.0 --base-fee 100
9 changes: 9 additions & 0 deletions dev/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ services:
build:
context: ../..
dockerfile: ./dev/validation_service/local.Dockerfile
environment:
ANVIL_URL: "http://anvil:8545"

anvil:
build:
dockerfile: ./anvil.Dockerfile
platform: linux/amd64
ports:
- 8545:8545

db:
image: postgres:13
Expand Down
2 changes: 1 addition & 1 deletion dev/docker/up
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -eou pipefail
script_dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

"${script_dir}"/compose pull
"${script_dir}"/compose up -d --build
"${script_dir}"/compose up -d --build
4 changes: 2 additions & 2 deletions dev/validation_service/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM rust:1-bullseye as builder
WORKDIR /code
COPY . .
RUN cargo build --release --package mls_validation_service
RUN cargo build --release --features test-utils --package mls_validation_service

FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y sqlite3 curl
COPY --from=builder /code/target/release/mls-validation-service /usr/local/bin/mls-validation-service
ENV RUST_LOG=info
CMD ["mls-validation-service"]
CMD ["mls-validation-service"]
3 changes: 3 additions & 0 deletions mls_validation_service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ rand = { workspace = true }
sha2.workspace = true
xmtp_id = { workspace = true, features = ["test-utils"] }
xmtp_mls = { workspace = true, features = ["test-utils"] }

[features]
test-utils = ["xmtp_id/test-utils"]
5 changes: 3 additions & 2 deletions xmtp_id/src/associations/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,12 @@ impl From<UnverifiedIdentityUpdate> for Vec<u8> {
}
}

impl From<&SmartContractWalletValidationResponseProto> for ValidationResponse {
fn from(value: &SmartContractWalletValidationResponseProto) -> Self {
impl From<SmartContractWalletValidationResponseProto> for ValidationResponse {
fn from(value: SmartContractWalletValidationResponseProto) -> Self {
Self {
is_valid: value.is_valid,
block_number: value.block_number,
error: value.error,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions xmtp_id/src/associations/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ impl SmartContractSignatureVerifier for MockSmartContractSignatureVerifier {
Ok(ValidationResponse {
is_valid: self.is_valid_signature,
block_number: Some(1),
error: None,
})
}
}
Expand Down
4 changes: 4 additions & 0 deletions xmtp_id/src/associations/verified_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ impl VerifiedSignature {
signature_bytes.to_vec(),
))
} else {
tracing::error!(
"Smart contract wallet signature is invalid {:?}",
response.error
);
Err(SignatureError::Invalid)
}
}
Expand Down
41 changes: 41 additions & 0 deletions xmtp_id/src/scw_verifier/chain_rpc_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ impl SmartContractSignatureVerifier for RpcSmartContractWalletVerifier {
Ok(ValidationResponse {
is_valid,
block_number: block_number.as_number().map(|n| n.0[0]),
error: None,
})
}
}
Expand All @@ -119,11 +120,51 @@ pub(crate) mod tests {
use super::*;
use ethers::{
abi::{self, Token},
core::{
k256::{elliptic_curve::SecretKey, Secp256k1},
utils::Anvil,
},
middleware::{MiddlewareBuilder, SignerMiddleware},
signers::{LocalWallet, Signer as _},
types::{H256, U256},
utils::hash_message,
};

abigen!(
CoinbaseSmartWallet,
"artifact/CoinbaseSmartWallet.json",
derives(serde::Serialize, serde::Deserialize)
);

abigen!(
CoinbaseSmartWalletFactory,
"artifact/CoinbaseSmartWalletFactory.json",
derives(serde::Serialize, serde::Deserialize)
);

pub struct SmartContracts {
coinbase_smart_wallet_factory:
CoinbaseSmartWalletFactory<SignerMiddleware<Provider<Http>, LocalWallet>>,
}

impl SmartContracts {
fn new(
coinbase_smart_wallet_factory: CoinbaseSmartWalletFactory<
SignerMiddleware<Provider<Http>, LocalWallet>,
>,
) -> Self {
Self {
coinbase_smart_wallet_factory,
}
}

pub fn coinbase_smart_wallet_factory(
&self,
) -> &CoinbaseSmartWalletFactory<SignerMiddleware<Provider<Http>, LocalWallet>> {
&self.coinbase_smart_wallet_factory
}
}

#[tokio::test]
async fn test_coinbase_smart_wallet() {
with_smart_contracts(|anvil, provider, client, smart_contracts| {
Expand Down
13 changes: 12 additions & 1 deletion xmtp_id/src/scw_verifier/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod chain_rpc_verifier;
mod remote_signature_verifier;

use std::{collections::HashMap, fs, path::Path};
use std::{collections::HashMap, env, fs, path::Path};

use crate::associations::AccountId;
use ethers::{
Expand Down Expand Up @@ -106,6 +106,7 @@ where
pub struct ValidationResponse {
pub is_valid: bool,
pub block_number: Option<u64>,
pub error: Option<String>,
}

pub struct MultiSmartContractSignatureVerifier {
Expand Down Expand Up @@ -151,6 +152,16 @@ impl MultiSmartContractSignatureVerifier {
info!("No upgraded chain url for chain {id}, using default.");
};
}

#[cfg(feature = "test-utils")]
if let Ok(url) = env::var("ANVIL_URL") {
info!("Adding anvil to the verifiers: {url}");
self.verifiers.insert(
"eip155:31337".to_string(),
Box::new(RpcSmartContractWalletVerifier::new(url)?),
);
}

Ok(self)
}

Expand Down
6 changes: 5 additions & 1 deletion xmtp_id/src/scw_verifier/remote_signature_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ where

let VerifySmartContractWalletSignaturesResponse { responses } = result;

Ok((&responses[0]).into())
Ok(responses
.into_iter()
.next()
.expect("Api given one request will return one response")
.into())
}
}

Expand Down
65 changes: 65 additions & 0 deletions xmtp_id/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod test {

use ethers::{
contract::abigen,
core::k256::{elliptic_curve::SecretKey, Secp256k1},
middleware::SignerMiddleware,
providers::{Http, Provider},
signers::LocalWallet,
Expand Down Expand Up @@ -56,6 +57,70 @@ pub mod test {
}
}

pub struct AnvilMeta {
pub keys: Vec<SecretKey<Secp256k1>>,
pub endpoint: String,
pub chain_id: u64,
}

#[cfg(not(target_arch = "wasm32"))]
pub async fn with_docker_smart_contracts<Func, Fut>(fun: Func)
where
Func: FnOnce(
AnvilMeta,
Provider<Http>,
SignerMiddleware<Provider<Http>, LocalWallet>,
SmartContracts,
) -> Fut,
Fut: futures::Future<Output = ()>,
{
use ethers::signers::Signer;
use ethers::utils::Anvil;
use std::sync::Arc;

// Spawn an anvil instance to get the keys and chain_id
let anvil = Anvil::new().port(8546u16).spawn();

let anvil_meta = AnvilMeta {
keys: anvil.keys().to_vec(),
chain_id: 31337,
endpoint: "http://localhost:8545".to_string(),
};

let keys = anvil.keys().to_vec();
let contract_deployer: LocalWallet = keys[9].clone().into();
let provider = Provider::<Http>::try_from(&anvil_meta.endpoint).unwrap();
let client = SignerMiddleware::new(
provider.clone(),
contract_deployer.clone().with_chain_id(anvil_meta.chain_id),
);
// 1. coinbase smart wallet
// deploy implementation for factory
let implementation = CoinbaseSmartWallet::deploy(Arc::new(client.clone()), ())
.unwrap()
.gas_price(100)
.send()
.await
.unwrap();
// deploy factory
let factory =
CoinbaseSmartWalletFactory::deploy(Arc::new(client.clone()), implementation.address())
.unwrap()
.gas_price(100)
.send()
.await
.unwrap();

let smart_contracts = SmartContracts::new(factory);
fun(
anvil_meta,
provider.clone(),
client.clone(),
smart_contracts,
)
.await
}

// anvil can't be used in wasm because it is a system binary
/// Test harness that loads a local anvil node with deployed smart contracts.
#[cfg(not(target_arch = "wasm32"))]
Expand Down
Loading

0 comments on commit 94f82b6

Please sign in to comment.