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

Took out a footgun with allowances #976

Merged
merged 7 commits into from
Nov 30, 2022

Conversation

DavidM-D
Copy link
Contributor

@DavidM-D DavidM-D commented Nov 25, 2022

Address's #871 .

I expect this is a reasonable final state for the library, but how should I manage the migration?

Create new function names for the new behavior and depreciate the old endpoints?

@austinabell
Copy link
Contributor

Create new function names for the new behavior and depreciate the old endpoints?

That would be the safest way, for sure. A little unfortunate that this small change touches three different endpoints currently. Unclear what the alternative would be, other than just making the change with a major release and documenting the migration/accepting breakages.

Comment on lines 560 to 563
match allowance {
0 => Allowance::Unlimited,
x => Allowance::limited(x).expect("This must be non zero"),
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like this should be:

Suggested change
match allowance {
0 => Allowance::Unlimited,
x => Allowance::limited(x).expect("This must be non zero"),
}
Allowance::limited(allowance).unwrap_or(Allowance::Unlimited)

Sorry if that doesn't compile, I didn't check it, but want to avoid the expect which comes with unnecessary bloat to compiled code size

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, much cleaner too

Comment on lines +11 to +17
/// Allow an access key to spend either an unlimited or limited amount of gas
// This wrapper prevents incorrect construction
#[derive(Clone, Copy)]
pub enum Allowance {
Unlimited,
Limited(NonZeroU128),
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should add a note that a zero allowance is allowed outside of promises. A zero allowance is allowed with add keys calls through RPC into the chain. This is just a special case of the host functions defining allowance as a ptr to a u64

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, what? You're saying you can create a function call access key without an allowance through rpc?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup. For example the following workspaces code:

use serde_json::json;
use workspaces::types::{KeyType, SecretKey};
use workspaces::{AccessKey, Account};

const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm";

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let worker = workspaces::sandbox().await?;
    let wasm = std::fs::read(STATUS_MSG_WASM_FILEPATH)?;
    let contract = worker.dev_deploy(&wasm).await?;

    let sk = SecretKey::from_seed(KeyType::ED25519, "test");
    let pk = sk.public_key();
    let ak = AccessKey::function_call_access(contract.id(), &["set_status"], Some(0));
    let account = Account::from_secret_key(contract.id().clone(), sk, &worker);

    contract
        .batch()
        .add_key(pk, ak)
        .transact()
        .await?
        .into_result()?;

    let outcome = account
        .call(contract.id(), "set_status")
        .args_json(json!({
            "message": "hello_world",
        }))
        .transact()
        .await?;
    println!("set_status: {:?}", outcome);

    Ok(())
}

would yield the error when calling into set_status:

Error: unable to broadcast the transaction to the network

Caused by:
    handler error: [An error happened during transaction execution: InvalidAccessKeyError(NotEnoughAllowance { account_id: AccountId("dev-20221130043518-92793473638831"), public_key: ed25519:DcA2MzgpJbrUATQLLceocVckhhAqrkingax4oJ9kZ847, allowance: 0, cost: 1561286367017332100000 })]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly had a vague intuition that this path would use the same logic as the runtime host function. Yeah, could document the difference. Honestly, there could be a reason (albeit bad) to add a key with no allowance just to record it as on-chain data. It's how some protocols verify accounts given there is no arbitrary signing right now

Copy link
Contributor

@austinabell austinabell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming might be a bit confusing but I don't know of a better solution here

@DavidM-D DavidM-D merged commit 2400a34 into near:master Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants