Skip to content

Commit

Permalink
Merge pull request #147 from ctindogaru/fix-gas-costs
Browse files Browse the repository at this point in the history
Optimise gas usage during the upgrade process
  • Loading branch information
TrevorJTClarke authored Apr 5, 2022
2 parents dfd1e2b + 941549c commit 32ca00a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 16 deletions.
Binary file modified sputnikdao-factory2/res/sputnikdao_factory2.wasm
Binary file not shown.
4 changes: 2 additions & 2 deletions sputnikdao-factory2/src/factory_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use near_sdk::serde_json;
use near_sdk::{env, AccountId, Balance, CryptoHash, Gas};

/// Gas spent on the call & account creation.
const CREATE_CALL_GAS: Gas = Gas(75_000_000_000_000);
const CREATE_CALL_GAS: Gas = Gas(40_000_000_000_000);

/// Gas allocated on the callback.
const ON_CREATE_CALL_GAS: Gas = Gas(10_000_000_000_000);

/// Leftover gas after creating promise and calling update.
const GAS_UPDATE_LEFTOVER: Gas = Gas(20_000_000_000_000);
const GAS_UPDATE_LEFTOVER: Gas = Gas(10_000_000_000_000);

const NO_DEPOSIT: Balance = 0;

Expand Down
Binary file modified sputnikdao2/res/sputnikdao2.wasm
Binary file not shown.
4 changes: 3 additions & 1 deletion sputnikdao2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use near_sdk::{
};

pub use crate::bounties::{Bounty, BountyClaim, VersionedBounty};
pub use crate::policy::{Policy, RoleKind, RolePermission, VersionedPolicy, VotePolicy};
pub use crate::policy::{
default_policy, Policy, RoleKind, RolePermission, VersionedPolicy, VotePolicy,
};
use crate::proposals::VersionedProposal;
pub use crate::proposals::{Proposal, ProposalInput, ProposalKind, ProposalStatus};
pub use crate::types::{Action, Config, OldAccountId, OLD_BASE_TOKEN};
Expand Down
2 changes: 1 addition & 1 deletion sputnikdao2/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub enum VersionedPolicy {
/// - non token weighted voting, requires 1/2 of the group to vote
/// - proposal & bounty bond is 1N
/// - proposal & bounty forgiveness period is 1 day
fn default_policy(council: Vec<AccountId>) -> Policy {
pub fn default_policy(council: Vec<AccountId>) -> Policy {
Policy {
roles: vec![
RolePermission {
Expand Down
20 changes: 11 additions & 9 deletions sputnikdao2/src/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ use crate::*;

const FACTORY_KEY: &[u8; 7] = b"FACTORY";
const ERR_MUST_BE_SELF_OR_FACTORY: &str = "ERR_MUST_BE_SELF_OR_FACTORY";
const UPDATE_GAS_LEFTOVER: Gas = Gas(5_000_000_000_000);
const UPDATE_GAS_LEFTOVER: Gas = Gas(10_000_000_000_000);
const FACTORY_UPDATE_GAS_LEFTOVER: Gas = Gas(15_000_000_000_000);
const NO_DEPOSIT: Balance = 0;

/// Gas for upgrading this contract on promise creation + deploying new contract.
pub const GAS_FOR_UPGRADE_SELF_DEPLOY: Gas = Gas(30_000_000_000_000);

pub const GAS_FOR_UPGRADE_REMOTE_DEPLOY: Gas = Gas(10_000_000_000_000);
pub const GAS_FOR_UPGRADE_SELF_DEPLOY: Gas = Gas(15_000_000_000_000);
pub const GAS_FOR_UPGRADE_REMOTE_DEPLOY: Gas = Gas(15_000_000_000_000);

/// Info about factory that deployed this contract and if auto-update is allowed.
#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
Expand Down Expand Up @@ -117,22 +115,26 @@ pub(crate) fn upgrade_using_factory(code_hash: Base58CryptoHash) {
#[allow(dead_code)]
pub(crate) fn upgrade_self(hash: &[u8]) {
let current_id = env::current_account_id();
let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_SELF_DEPLOY;
let input = env::storage_read(hash).expect("ERR_NO_HASH");
let promise_id = env::promise_batch_create(&current_id);
env::promise_batch_action_deploy_contract(promise_id, &input);
env::promise_batch_action_function_call(promise_id, "migrate", &[], NO_DEPOSIT, attached_gas);
env::promise_batch_action_function_call(
promise_id,
"migrate",
&[],
NO_DEPOSIT,
env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_SELF_DEPLOY,
);
}

pub(crate) fn upgrade_remote(receiver_id: &AccountId, method_name: &str, hash: &[u8]) {
let input = env::storage_read(hash).expect("ERR_NO_HASH");
let promise_id = env::promise_batch_create(receiver_id);
let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_REMOTE_DEPLOY;
env::promise_batch_action_function_call(
promise_id,
method_name,
&input,
NO_DEPOSIT,
attached_gas,
env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_REMOTE_DEPLOY,
);
}
78 changes: 75 additions & 3 deletions sputnikdao2/tests/test_general.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::collections::HashMap;

use near_sdk::json_types::U128;
use near_sdk::serde_json::json;
use near_sdk::{env, AccountId};
use near_sdk_sim::{call, to_yocto, view};
use near_sdk_sim::{call, init_simulator, to_yocto, view};

use crate::utils::*;
use sputnik_staking::User;
use sputnikdao2::{
Action, BountyClaim, BountyOutput, Policy, Proposal, ProposalInput, ProposalKind,
ProposalOutput, ProposalStatus, RoleKind, RolePermission, VersionedPolicy, VotePolicy,
default_policy, Action, BountyClaim, BountyOutput, Config, Policy, Proposal, ProposalInput,
ProposalKind, ProposalOutput, ProposalStatus, RoleKind, RolePermission, VersionedPolicy,
VotePolicy,
};

mod utils;
Expand All @@ -17,6 +19,76 @@ fn user(id: u32) -> AccountId {
format!("user{}", id).parse().unwrap()
}

#[test]
fn test_large_policy() {
let root = init_simulator(None);
let factory = setup_factory(&root);
factory
.user_account
.call(
factory.user_account.account_id.clone(),
"new",
&[],
near_sdk_sim::DEFAULT_GAS,
0,
)
.assert_success();

let config = Config {
name: "testdao".to_string(),
purpose: "to test".to_string(),
metadata: Base64VecU8(vec![]),
};
let mut policy = default_policy(vec![root.account_id()]);
const NO_OF_COUNCILS: u32 = 10;
const USERS_PER_COUNCIL: u32 = 100;
for council_no in 0..NO_OF_COUNCILS {
let mut council = vec![];
let user_id_start = council_no * USERS_PER_COUNCIL;
let user_id_end = user_id_start + USERS_PER_COUNCIL;
for user_id in user_id_start..user_id_end {
council.push(user(user_id));
}

let role = RolePermission {
name: format!("council{}", council_no),
kind: RoleKind::Group(council.into_iter().collect()),
permissions: vec![
"*:AddProposal".to_string(),
"*:VoteApprove".to_string(),
"*:VoteReject".to_string(),
"*:VoteRemove".to_string(),
"*:Finalize".to_string(),
]
.into_iter()
.collect(),
vote_policy: HashMap::default(),
};
policy.add_or_update_role(&role);
}

let params = json!({ "config": config, "policy": policy })
.to_string()
.into_bytes();

call!(
root,
factory.create(
AccountId::new_unchecked("testdao".to_string()),
Base64VecU8(params)
),
deposit = to_yocto("10")
)
.assert_success();

let dao_account_id = AccountId::new_unchecked("testdao.factory".to_string());
let dao_list = factory
.user_account
.view(factory.user_account.account_id.clone(), "get_dao_list", &[])
.unwrap_json::<Vec<AccountId>>();
assert_eq!(dao_list, vec![dao_account_id.clone()]);
}

#[test]
fn test_multi_council() {
let (root, dao) = setup_dao();
Expand Down

0 comments on commit 32ca00a

Please sign in to comment.