-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix: exclude host only functions from client (#1359)
* adding test * fmt * clippy * exclude fns starting with __ * revert erroneous change * Update cmd/crates/soroban-spec-typescript/src/lib.rs readability Co-authored-by: Willem Wyndham <[email protected]> * remove extraneous iterator conversions * Update cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml --------- Co-authored-by: Willem Wyndham <[email protected]>
- Loading branch information
1 parent
7eec383
commit 610c6f9
Showing
6 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "test_custom_account" | ||
version = "21.0.0-rc.1" | ||
authors = ["Stellar Development Foundation <[email protected]>"] | ||
license = "Apache-2.0" | ||
edition = "2021" | ||
publish = false | ||
rust-version.workspace = true | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
doctest = false | ||
|
||
[dependencies] | ||
soroban-sdk = { workspace = true } | ||
|
||
[dev-dependencies] | ||
soroban-sdk = { workspace = true, features = ["testutils"]} |
131 changes: 131 additions & 0 deletions
131
cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_account/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
#![no_std] | ||
use soroban_sdk::{ | ||
auth::{Context, CustomAccountInterface}, | ||
contract, contracterror, contractimpl, contracttype, | ||
crypto::Hash, | ||
symbol_short, vec, Address, Bytes, BytesN, Env, Symbol, Vec, | ||
}; | ||
|
||
#[contract] | ||
pub struct Contract; | ||
|
||
#[contracterror] | ||
#[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
pub enum Error { | ||
NotFound = 1, | ||
NotPermitted = 2, | ||
ClientDataJsonChallengeIncorrect = 3, | ||
Secp256r1PublicKeyParse = 4, | ||
Secp256r1SignatureParse = 5, | ||
Secp256r1VerifyFailed = 6, | ||
JsonParseError = 7, | ||
InvalidContext = 8, | ||
AlreadyInited = 9, | ||
NotInited = 10, | ||
} | ||
|
||
const SIGNERS: Symbol = symbol_short!("sigs"); | ||
const FACTORY: Symbol = symbol_short!("factory"); | ||
const SUDO_SIGNER: Symbol = symbol_short!("sudo_sig"); | ||
|
||
#[contractimpl] | ||
impl Contract { | ||
pub fn extend_ttl(env: &Env) { | ||
let max_ttl = env.storage().max_ttl(); | ||
let contract_address = env.current_contract_address(); | ||
|
||
env.storage().instance().extend_ttl(max_ttl, max_ttl); | ||
env.deployer() | ||
.extend_ttl(contract_address.clone(), max_ttl, max_ttl); | ||
env.deployer() | ||
.extend_ttl_for_code(contract_address.clone(), max_ttl, max_ttl); | ||
env.deployer() | ||
.extend_ttl_for_contract_instance(contract_address.clone(), max_ttl, max_ttl); | ||
} | ||
pub fn init(env: Env, id: Bytes, pk: BytesN<65>, factory: Address) -> Result<(), Error> { | ||
if env.storage().instance().has(&SUDO_SIGNER) { | ||
return Err(Error::AlreadyInited); | ||
} | ||
|
||
let max_ttl = env.storage().max_ttl(); | ||
|
||
env.storage().persistent().set(&id, &pk); | ||
env.storage().persistent().extend_ttl(&id, max_ttl, max_ttl); | ||
|
||
env.storage().instance().set(&SUDO_SIGNER, &id); | ||
env.storage().instance().set(&FACTORY, &factory); | ||
env.storage().instance().set(&SIGNERS, &vec![&env, id]); | ||
|
||
Self::extend_ttl(&env); | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
#[contracttype] | ||
pub struct Signature { | ||
pub id: BytesN<32>, | ||
pub authenticator_data: Bytes, | ||
pub client_data_json: Bytes, | ||
pub signature: BytesN<64>, | ||
} | ||
|
||
#[derive(Debug)] | ||
struct ClientDataJson<'a> { | ||
challenge: &'a str, | ||
} | ||
|
||
#[contractimpl] | ||
impl CustomAccountInterface for Contract { | ||
type Error = Error; | ||
type Signature = Signature; | ||
|
||
#[allow(non_snake_case)] | ||
fn __check_auth( | ||
env: Env, | ||
signature_payload: Hash<32>, | ||
signature: Signature, | ||
auth_contexts: Vec<Context>, | ||
) -> Result<(), Error> { | ||
// Only the sudo signer can `add_sig`, `rm_sig` and `resudo` | ||
for context in auth_contexts.iter() { | ||
match context { | ||
Context::Contract(c) => { | ||
if c.contract == env.current_contract_address() | ||
&& (c.fn_name == Symbol::new(&env, "add_sig") | ||
|| c.fn_name == Symbol::new(&env, "rm_sig") | ||
|| c.fn_name == Symbol::new(&env, "resudo")) | ||
&& signature.id | ||
!= env | ||
.storage() | ||
.instance() | ||
.get::<Symbol, BytesN<32>>(&SUDO_SIGNER) | ||
.ok_or(Error::NotFound)? | ||
{ | ||
return Err(Error::NotPermitted); | ||
} | ||
} | ||
Context::CreateContractHostFn(_) => return Err(Error::InvalidContext), | ||
}; | ||
} | ||
|
||
// Dummy public key verification check | ||
env.storage() | ||
.persistent() | ||
.get::<BytesN<32>, Bytes>(&signature.id) | ||
.ok_or(Error::NotFound)?; | ||
if signature_payload.to_bytes().len() != 32 { | ||
return Err(Error::NotPermitted); | ||
} | ||
|
||
let client_data = ClientDataJson { | ||
challenge: "dummy_challenge", | ||
}; | ||
|
||
if client_data.challenge != "dummy_challenge" { | ||
return Err(Error::ClientDataJsonChallengeIncorrect); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters