Skip to content

Commit

Permalink
Add test script for projects/eth_wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
DemesneGH committed Nov 27, 2024
1 parent c9b4187 commit e236453
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 36 deletions.
1 change: 1 addition & 0 deletions ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if [ "$STD" ]; then
./test_udp_socket.sh
./test_tls_client.sh
./test_tls_server.sh
./test_eth_wallet.sh
fi

popd
3 changes: 3 additions & 0 deletions projects/web3/eth_wallet/host/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ pub enum Command {
/// Sign a transaction.
#[structopt(name = "sign-transaction")]
SignTransaction(SignTransactionOpt),
/// Run tests
#[structopt(name = "test")]
Test,
}

#[derive(Debug, StructOpt)]
Expand Down
111 changes: 75 additions & 36 deletions projects/web3/eth_wallet/host/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.

mod cli;
mod tests;

use optee_teec::{Context, Operation, ParamType, Uuid};
use optee_teec::{ParamNone, ParamTmpRef, ParamValue};
Expand Down Expand Up @@ -56,54 +57,92 @@ fn invoke_command(command: proto::Command, input: &[u8]) -> optee_teec::Result<V
}
}

pub fn create_wallet() -> Result<uuid::Uuid> {
let serialized_output = invoke_command(proto::Command::CreateWallet, &[])?;
let output: proto::CreateWalletOutput = bincode::deserialize(&serialized_output)?;
Ok(output.wallet_id)
}

pub fn remove_wallet(wallet_id: uuid::Uuid) -> Result<()> {
let input = proto::RemoveWalletInput { wallet_id };
let _output = invoke_command(proto::Command::RemoveWallet, &bincode::serialize(&input)?)?;
Ok(())
}

pub fn derive_address(wallet_id: uuid::Uuid, hd_path: &str) -> Result<[u8; 20]> {
let input = proto::DeriveAddressInput {
wallet_id,
hd_path: hd_path.to_string(),
};
let serialized_output =
invoke_command(proto::Command::DeriveAddress, &bincode::serialize(&input)?)?;
let output: proto::DeriveAddressOutput = bincode::deserialize(&serialized_output)?;
Ok(output.address)
}

pub fn sign_transaction(
wallet_id: uuid::Uuid,
hd_path: &str,
chain_id: u64,
nonce: u128,
to: [u8; 20],
value: u128,
gas_price: u128,
gas: u128,
) -> Result<Vec<u8>> {
let transaction = proto::EthTransaction {
chain_id,
nonce,
to: Some(to),
value,
gas_price,
gas,
data: vec![],
};
let input = proto::SignTransactionInput {
wallet_id,
hd_path: hd_path.to_string(),
transaction,
};
let serialized_output = invoke_command(
proto::Command::SignTransaction,
&bincode::serialize(&input)?,
)?;
let output: proto::SignTransactionOutput = bincode::deserialize(&serialized_output)?;
Ok(output.signature)
}

fn main() -> Result<()> {
let args = cli::Opt::from_args();
match args.command {
cli::Command::CreateWallet(_opt) => {
let serialized_output = invoke_command(proto::Command::CreateWallet, &[])?;
let output: proto::CreateWalletOutput = bincode::deserialize(&serialized_output)?;
println!("Wallet ID: {}", output.wallet_id);
let wallet_id = create_wallet()?;
println!("Wallet ID: {}", wallet_id);
}
cli::Command::RemoveWallet(opt) => {
let input = proto::RemoveWalletInput {
wallet_id: opt.wallet_id,
};
let _output =
invoke_command(proto::Command::RemoveWallet, &bincode::serialize(&input)?)?;
remove_wallet(opt.wallet_id)?;
println!("Wallet removed");
}
cli::Command::DeriveAddress(opt) => {
let input = proto::DeriveAddressInput {
wallet_id: opt.wallet_id,
hd_path: opt.hd_path,
};
let serialized_output =
invoke_command(proto::Command::DeriveAddress, &bincode::serialize(&input)?)?;
let output: proto::DeriveAddressOutput = bincode::deserialize(&serialized_output)?;
println!("Address: 0x{}", hex::encode(&output.address));
println!("Public key: {}", hex::encode(&output.public_key));
let address = derive_address(opt.wallet_id, &opt.hd_path)?;
println!("Address: 0x{}", hex::encode(&address));
}
cli::Command::SignTransaction(opt) => {
let transaction = proto::EthTransaction {
chain_id: opt.chain_id,
nonce: opt.nonce,
to: Some(opt.to),
value: opt.value,
gas_price: opt.gas_price,
gas: opt.gas,
data: vec![],
};
let input = proto::SignTransactionInput {
wallet_id: opt.wallet_id,
hd_path: opt.hd_path,
transaction,
};
let serialized_output = invoke_command(
proto::Command::SignTransaction,
&bincode::serialize(&input)?,
let signature = sign_transaction(
opt.wallet_id,
&opt.hd_path,
opt.chain_id,
opt.nonce,
opt.to,
opt.value,
opt.gas_price,
opt.gas,
)?;
let output: proto::SignTransactionOutput = bincode::deserialize(&serialized_output)?;
println!("Signature: {}", hex::encode(&output.signature));
println!("Signature: {}", hex::encode(&signature));
}
cli::Command::Test => {
tests::tests::test_workflow();
println!("Tests passed");
}
_ => {
bail!("Unsupported command");
Expand Down
20 changes: 20 additions & 0 deletions projects/web3/eth_wallet/host/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pub mod tests {
use crate::*;

pub fn test_workflow() {
// Simulate the workflow of creating a wallet, deriving an address, and signing a transaction
let wallet_id = create_wallet().unwrap();
let address = derive_address(wallet_id, "m/44'/60'/0'/0/0").unwrap();
let result = sign_transaction(
wallet_id,
"m/44'/60'/0'/0/0",
5,
0,
address,
100,
1000000000,
21000,
);
assert!(result.is_ok());
}
}
42 changes: 42 additions & 0 deletions tests/test_eth_wallet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

set -xe

# Include base script
source setup.sh

# Copy TA and host binary
cp ../projects/web3/eth_wallet/ta/target/$TARGET_TA/release/*.ta shared
cp ../projects/web3/eth_wallet/host/target/$TARGET_HOST/release/eth_wallet-rs shared

# Run script specific commands in QEMU
run_in_qemu "cp *.ta /lib/optee_armtz/\n"
run_in_qemu "./eth_wallet-rs test\n"
run_in_qemu "^C"

# Script specific checks
{
grep -q "Tests passed" screenlog.0
} || {
cat -v screenlog.0
false
}

rm screenlog.0

0 comments on commit e236453

Please sign in to comment.