diff --git a/Makefile b/Makefile index 9d89b02610..1d82ff2949 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ reset: backup: - cd ~ && rsync -av --exclude db/ --exclude logs/ ~/.0L ~/0L_backup_$(shell date +"%m-%d-%y-%T") + cd ~ && rsync -av --exclude db/ --exclude logs/ ~/.0L/* ~/0L_backup_$(shell date +"%m-%d-%y-%T") confirm: @read -p "Continue (y/n)?" CONT; \ @@ -145,22 +145,13 @@ confirm: exit 1; \ fi \ -danger-delete-all: - @echo THIS WILL WIPE ALL YOUR FILES in ${HOME}/.0L - @echo it will also make a backup at ${HOME}/backup_0L/ - @echo the files github_token.txt, autopay_batch.json, set_layout, ./vdf_proofs/ and ./blocks/ will be returned to ${HOME}/.0L/ - make confirm - make backup - rm -rf ${HOME}/.0L | true - mkdir ${HOME}/.0L/ - make danger-restore danger-restore: - cp ${HOME}/backup_0L/github_token.txt ${HOME}/.0L/ | true - cp ${HOME}/backup_0L/autopay_batch.json ${HOME}/.0L/ | true - rsync -rtv ${HOME}/backup_0L/blocks/ ${HOME}/.0L/blocks | true - rsync -rtv ${HOME}/backup_0L/vdf_proofs/ ${HOME}/.0L/vdf_proofs | true - rsync -rtv ${HOME}/backup_0L/set_layout.toml ${HOME}/.0L/ | true + cp ${HOME}/0L_backup/github_token.txt ${HOME}/.0L/ | true + cp ${HOME}/0L_backup/autopay_batch.json ${HOME}/.0L/ | true + rsync -rtv ${HOME}/0L_backup/blocks/ ${HOME}/.0L/blocks | true + rsync -rtv ${HOME}/0L_backup/vdf_proofs/ ${HOME}/.0L/vdf_proofs | true + rsync -rtv ${HOME}/0L_backup/set_layout.toml ${HOME}/.0L/ | true @@ -212,6 +203,12 @@ gen-make-pull: --shared-backend ${GENESIS_REMOTE} \ --pull-request-user ${GITHUB_USER} +gen-delete-fork: + cargo run -p diem-genesis-tool ${CARGO_ARGS} -- create-repo \ + --repo-name ${REPO_NAME} \ + --repo-owner ${REPO_ORG} \ + --shared-backend ${GENESIS_REMOTE} \ + --delete-repo-user ${GITHUB_USER} gen-onboard: cargo run -p onboard ${CARGO_ARGS} -- val --genesis-ceremony @@ -308,7 +305,7 @@ genesis: #### NODE MANAGEMENT #### start: # run in foreground. Only for testing, use a daemon for net. - NODE_ENV=error cargo run -p diem-node -- --config ${DATA_PATH}/validator.node.yaml + RUST_LOG=error cargo run -p diem-node -- --config ${DATA_PATH}/validator.node.yaml # Start a fullnode instead of a validator node start-full: diff --git a/config/management/genesis/src/ol_create_repo.rs b/config/management/genesis/src/ol_create_repo.rs index 3d5af86a21..dff5506161 100644 --- a/config/management/genesis/src/ol_create_repo.rs +++ b/config/management/genesis/src/ol_create_repo.rs @@ -22,6 +22,8 @@ pub struct CreateGenesisRepo { pub repo_name: String, #[structopt(long)] pub pull_request_user: Option, + #[structopt(long)] + pub delete_repo_user: Option, } impl CreateGenesisRepo { @@ -55,6 +57,15 @@ impl CreateGenesisRepo { e.to_string(), )), } + } else if let Some(user) = self.delete_repo_user{ + match github.delete_own_repo(&user, &config.repository) { + Ok(_) => Ok("created pull request to genesis repo".to_string()), + Err(e) => Err(Error::StorageWriteError( + "github", + "pull request", + e.to_string(), + )), + } } else { // Fork the genesis coordination repo into a personal repo match github.fork_genesis_repo(&self.repo_owner, &self.repo_name) { diff --git a/language/diem-framework/modules/0L/Globals.move b/language/diem-framework/modules/0L/Globals.move index 61199dc414..45e121a87f 100644 --- a/language/diem-framework/modules/0L/Globals.move +++ b/language/diem-framework/modules/0L/Globals.move @@ -34,9 +34,7 @@ module Globals { epoch_slow_wallet_unlock: u64, } - //////////////////// - //// Constants //// - /////////////////// + const COIN_SCALING_FACTOR: u64 = 1000000; /// Get the epoch length public fun get_epoch_length(): u64 { @@ -48,6 +46,11 @@ module Globals { get_constants().max_validators_per_set } + /// Get the epoch length + public fun get_coin_scaling_factor(): u64 { + COIN_SCALING_FACTOR + } + /// Get max validator per epoch public fun get_subsidy_ceiling_gas(): u64 { get_constants().subsidy_ceiling_gas @@ -58,7 +61,7 @@ module Globals { get_constants().vdf_difficulty } - /// Get the current vdf_difficulty + /// Get the current vdf_difficulty public fun get_vdf_security(): u64 { 512 } @@ -81,14 +84,14 @@ module Globals { /// Get the constants for the current network fun get_constants(): GlobalConstants { - let coin_scale = 1000000; // Diem::scaling_factor(); - assert(coin_scale == Diem::scaling_factor(), Errors::invalid_argument(070001)); + // let coin_scale = 1000000; // Diem::scaling_factor(); + assert(COIN_SCALING_FACTOR == Diem::scaling_factor(), Errors::invalid_argument(070001)); if (Testnet::is_testnet()) { return GlobalConstants { epoch_length: 60, // seconds max_validators_per_set: 100, - subsidy_ceiling_gas: 296 * coin_scale, + subsidy_ceiling_gas: 296 * COIN_SCALING_FACTOR, vdf_difficulty: 100, epoch_mining_thres_lower: 1, epoch_mining_thres_upper: 1000, // upper bound unlimited @@ -98,9 +101,9 @@ module Globals { if (StagingNet::is_staging_net()) { return GlobalConstants { - epoch_length: 60 * 40, // 20 mins, enough for a hard miner proof. + epoch_length: 60 * 40, // 40 mins, enough for a hard miner proof. max_validators_per_set: 100, - subsidy_ceiling_gas: 8640000 * coin_scale, + subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR, vdf_difficulty: 120000000, epoch_mining_thres_lower: 1, epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof. @@ -115,11 +118,11 @@ module Globals { // target max block time: 2 secs // target transaction per sec max gas: 20 // uses "scaled representation", since there are no decimals. - subsidy_ceiling_gas: 8640000 * coin_scale, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value. + subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value. vdf_difficulty: 120000000, // FYI approx 30 mins per proof on 2020 macbook pro 2.5 ghz quadcore epoch_mining_thres_lower: 7, // NOTE: bootstrapping, allowance for operator error. epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof. - epoch_slow_wallet_unlock: 1000 * coin_scale, // approx 10 years for largest accounts in genesis. + epoch_slow_wallet_unlock: 1000 * COIN_SCALING_FACTOR, // approx 10 years for largest accounts in genesis. } } } diff --git a/language/diem-framework/modules/0L_transaction_scripts/ol_account.move b/language/diem-framework/modules/0L_transaction_scripts/ol_account.move index ab3889ffde..a1d5deb0e7 100644 --- a/language/diem-framework/modules/0L_transaction_scripts/ol_account.move +++ b/language/diem-framework/modules/0L_transaction_scripts/ol_account.move @@ -11,7 +11,27 @@ module AccountScripts { use 0x1::DiemAccount; use 0x1::GAS::GAS; use 0x1::ValidatorConfig; - + use 0x1::Globals; + + public(script) fun create_user_by_coin_tx( + sender: signer, + account: address, + authkey_prefix: vector, + unscaled_value: u64, + ) { + // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR. + let value = unscaled_value * Globals::get_coin_scaling_factor(); + let new_account_address = DiemAccount::create_user_account_with_coin( + &sender, + account, + authkey_prefix, + value, + ); + + // Check the account exists and the balance is 0 + assert(DiemAccount::balance(new_account_address) > 0, 01); + } + public(script) fun create_acc_user( sender: signer, challenge: vector, diff --git a/language/diem-framework/modules/0L_transaction_scripts/ol_transfer.move b/language/diem-framework/modules/0L_transaction_scripts/ol_transfer.move new file mode 100644 index 0000000000..26ca4767c0 --- /dev/null +++ b/language/diem-framework/modules/0L_transaction_scripts/ol_transfer.move @@ -0,0 +1,29 @@ +// For transferring balance between accounts. +address 0x1 { +module TransferScripts { + use 0x1::DiemAccount; + use 0x1::GAS::GAS; + use 0x1::Globals; + use 0x1::Signer; + + public(script) fun balance_transfer( + sender: signer, + destination: address, + unscaled_value: u64, + ) { + // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR. + let value = unscaled_value * Globals::get_coin_scaling_factor(); + let sender_addr = Signer::address_of(&sender); + let sender_balance_pre = DiemAccount::balance(sender_addr); + let destination_balance_pre = DiemAccount::balance(destination); + + let with_cap = DiemAccount::extract_withdraw_capability(&sender); + DiemAccount::pay_from(&with_cap, destination, value, b"balance_transfer", b""); + DiemAccount::restore_withdraw_capability(with_cap); + + assert(DiemAccount::balance(destination) > destination_balance_pre, 01); + assert(DiemAccount::balance(sender_addr) < sender_balance_pre, 02); + } + +} +} \ No newline at end of file diff --git a/language/diem-framework/modules/DiemAccount.move b/language/diem-framework/modules/DiemAccount.move index b87527d0ef..b9be434882 100644 --- a/language/diem-framework/modules/DiemAccount.move +++ b/language/diem-framework/modules/DiemAccount.move @@ -155,7 +155,6 @@ module DiemAccount { const MAX_U64: u128 = 18446744073709551615; - /////// 0L ///////// /// The `DiemAccount` resource is not in the required state const EACCOUNT: u64 = 12010; /// Tried to deposit a coin whose value was zero @@ -195,6 +194,10 @@ module DiemAccount { const EWRITESET_MANAGER: u64 = 120123; /// An account cannot be created at the reserved core code address of 0x1 const ECANNOT_CREATE_AT_CORE_CODE: u64 = 120124; + + //////// 0L //////// + const EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN: u64 = 120125; + /////// 0L end ///////// /// Prologue errors. These are separated out from the other errors in this @@ -472,7 +475,7 @@ module DiemAccount { add_currencies_for_account(&new_signer, false); make_account(new_signer, auth_key_prefix); - onboarding_gas_transfer(sender, new_account_address); + onboarding_gas_transfer(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Init the miner state // this verifies the VDF proof, which we use to rate limit account creation. // account will not be created if this step fails. @@ -482,6 +485,26 @@ module DiemAccount { new_account_address } + /////// 0L //////// + // Function code: 01 + public fun create_user_account_with_coin( + sender: &signer, + new_account: address, + new_account_authkey_prefix: vector, + value: u64, + ):address acquires AccountOperationsCapability, Balance, CumulativeDeposits, DiemAccount { + + // let (new_account_address, auth_key_prefix) = VDF::extract_address_from_challenge(challenge); + let new_signer = create_signer(new_account); + Roles::new_user_role_with_proof(&new_signer); + Event::publish_generator(&new_signer); + add_currencies_for_account(&new_signer, false); + make_account(new_signer, new_account_authkey_prefix); + + onboarding_gas_transfer(sender, new_account, value); + new_account + } + /////// 0L //////// // spec fun create_user_account { // include AddCurrencyForAccountEnsures{addr: new_account_address}; @@ -576,9 +599,9 @@ module DiemAccount { // Transfer for owner - onboarding_gas_transfer(sender, new_account_address); + onboarding_gas_transfer(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer(sender, op_address); + onboarding_gas_transfer(sender, op_address, BOOTSTRAP_COIN_VALUE); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -684,9 +707,9 @@ print(&509); print(&510); // the miner who is upgrading may have coins, but better safe... // Transfer for owner - onboarding_gas_transfer(sender, new_account_address); + onboarding_gas_transfer(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer(sender, op_address); + onboarding_gas_transfer(sender, op_address, BOOTSTRAP_COIN_VALUE); print(&510); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -1557,19 +1580,27 @@ print(&511); // using "spec schema" ? fun onboarding_gas_transfer( payer_sig: &signer, - payee: address + payee: address, + value: u64, ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits { //////// 0L //////// let payer_addr = Signer::address_of(payer_sig); let account_balance = borrow_global_mut>(payer_addr); let balance_coin = &mut account_balance.coin; + + // value needs to be greater than boostrapping value + assert( + value >= BOOTSTRAP_COIN_VALUE, + Errors::limit_exceeded(EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN) + ); + // Doubly check balance exists. assert( - Diem::value(balance_coin) > BOOTSTRAP_COIN_VALUE, + Diem::value(balance_coin) > value, Errors::limit_exceeded(EINSUFFICIENT_BALANCE) ); // Should abort if the let metadata = b"onboarding coin transfer"; - let coin_to_deposit = Diem::withdraw(balance_coin, BOOTSTRAP_COIN_VALUE); + let coin_to_deposit = Diem::withdraw(balance_coin, value); deposit( payer_addr, payee, @@ -1595,9 +1626,7 @@ print(&511); oper: address, ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits { CoreAddresses::assert_vm(vm); - onboarding_gas_transfer(owner_sig, oper); - - + onboarding_gas_transfer(owner_sig, oper, BOOTSTRAP_COIN_VALUE); } /// Rotate the authentication key for the account under cap.account_address diff --git a/language/diem-framework/modules/doc/DiemAccount.md b/language/diem-framework/modules/doc/DiemAccount.md index acdc143959..9811746a0a 100644 --- a/language/diem-framework/modules/doc/DiemAccount.md +++ b/language/diem-framework/modules/doc/DiemAccount.md @@ -32,6 +32,7 @@ before and after every transaction. - [Function `initialize_escrow_root`](#0x1_DiemAccount_initialize_escrow_root) - [Function `initialize`](#0x1_DiemAccount_initialize) - [Function `create_user_account_with_proof`](#0x1_DiemAccount_create_user_account_with_proof) +- [Function `create_user_account_with_coin`](#0x1_DiemAccount_create_user_account_with_coin) - [Function `create_validator_account_with_proof`](#0x1_DiemAccount_create_validator_account_with_proof) - [Function `upgrade_validator_account_with_proof`](#0x1_DiemAccount_upgrade_validator_account_with_proof) - [Function `has_published_account_limits`](#0x1_DiemAccount_has_published_account_limits) @@ -804,6 +805,15 @@ Tried to add a balance in a currency that this account already has + + + + +
const EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN: u64 = 120125;
+
+ + + An account cannot be created at the reserved core code address of 0x1 @@ -1406,7 +1416,7 @@ Initialize this module. This is only callable from genesis. add_currencies_for_account<GAS>(&new_signer, false); make_account(new_signer, auth_key_prefix); - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Init the miner state // this verifies the VDF proof, which we use to rate limit account creation. // account will not be created if this step fails. @@ -1419,6 +1429,44 @@ Initialize this module. This is only callable from genesis. + + + + +## Function `create_user_account_with_coin` + + + +
public fun create_user_account_with_coin(sender: &signer, new_account: address, new_account_authkey_prefix: vector<u8>, value: u64): address
+
+ + + +
+Implementation + + +
public fun create_user_account_with_coin(
+    sender: &signer,
+    new_account: address,
+    new_account_authkey_prefix: vector<u8>,
+    value: u64,
+):address acquires AccountOperationsCapability, Balance, CumulativeDeposits, DiemAccount {
+
+    // let (new_account_address, auth_key_prefix) = VDF::extract_address_from_challenge(challenge);
+    let new_signer = create_signer(new_account);
+    Roles::new_user_role_with_proof(&new_signer);
+    Event::publish_generator(&new_signer);
+    add_currencies_for_account<GAS>(&new_signer, false);
+    make_account(new_signer, new_account_authkey_prefix);
+
+    onboarding_gas_transfer<GAS>(sender, new_account, value);
+    new_account
+}
+
+ + +
@@ -1519,9 +1567,9 @@ Initialize this module. This is only callable from genesis. // Transfer for owner - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer<GAS>(sender, op_address); + onboarding_gas_transfer<GAS>(sender, op_address, BOOTSTRAP_COIN_VALUE); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -1638,9 +1686,9 @@ print(&509); print(&510); // the miner who is upgrading may have coins, but better safe... // Transfer for owner - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer<GAS>(sender, op_address); + onboarding_gas_transfer<GAS>(sender, op_address, BOOTSTRAP_COIN_VALUE); print(&510); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -3024,7 +3072,7 @@ subject to the dual attestation protocol -
fun onboarding_gas_transfer<Token: store>(payer_sig: &signer, payee: address)
+
fun onboarding_gas_transfer<Token: store>(payer_sig: &signer, payee: address, value: u64)
 
@@ -3035,19 +3083,27 @@ subject to the dual attestation protocol
fun onboarding_gas_transfer<Token: store>(
     payer_sig: &signer,
-    payee: address
+    payee: address,
+    value: u64,
 ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits { //////// 0L ////////
     let payer_addr = Signer::address_of(payer_sig);
     let account_balance = borrow_global_mut<Balance<Token>>(payer_addr);
     let balance_coin = &mut account_balance.coin;
+
+    // value needs to be greater than boostrapping value
+    assert(
+        value >= BOOTSTRAP_COIN_VALUE,
+        Errors::limit_exceeded(EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN)
+    );
+
     // Doubly check balance exists.
     assert(
-        Diem::value(balance_coin) > BOOTSTRAP_COIN_VALUE,
+        Diem::value(balance_coin) > value,
         Errors::limit_exceeded(EINSUFFICIENT_BALANCE)
     );
     // Should abort if the
     let metadata = b"onboarding coin transfer";
-    let coin_to_deposit = Diem::withdraw(balance_coin, BOOTSTRAP_COIN_VALUE);
+    let coin_to_deposit = Diem::withdraw(balance_coin, value);
     deposit<Token>(
         payer_addr,
         payee,
@@ -3083,9 +3139,7 @@ subject to the dual attestation protocol
   oper: address,
 ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits {
   CoreAddresses::assert_vm(vm);
-  onboarding_gas_transfer<GAS>(owner_sig, oper);
-
-
+  onboarding_gas_transfer<GAS>(owner_sig, oper, BOOTSTRAP_COIN_VALUE);
 }
 
diff --git a/language/diem-framework/modules/doc/Globals.md b/language/diem-framework/modules/doc/Globals.md index 5363b0c82c..7e7deb41ea 100644 --- a/language/diem-framework/modules/doc/Globals.md +++ b/language/diem-framework/modules/doc/Globals.md @@ -13,8 +13,10 @@ This module provides global variables and constants that have no specific owner - [Summary](#@Summary_0) - [Struct `GlobalConstants`](#0x1_Globals_GlobalConstants) +- [Constants](#@Constants_1) - [Function `get_epoch_length`](#0x1_Globals_get_epoch_length) - [Function `get_max_validators_per_set`](#0x1_Globals_get_max_validators_per_set) +- [Function `get_coin_scaling_factor`](#0x1_Globals_get_coin_scaling_factor) - [Function `get_subsidy_ceiling_gas`](#0x1_Globals_get_subsidy_ceiling_gas) - [Function `get_vdf_difficulty`](#0x1_Globals_get_vdf_difficulty) - [Function `get_vdf_security`](#0x1_Globals_get_vdf_security) @@ -104,6 +106,20 @@ epoch by a miner to remain compliant + + +## Constants + + + + + + +
const COIN_SCALING_FACTOR: u64 = 1000000;
+
+ + + ## Function `get_epoch_length` @@ -152,6 +168,31 @@ Get max validator per epoch + + + + +## Function `get_coin_scaling_factor` + +Get the epoch length + + +
public fun get_coin_scaling_factor(): u64
+
+ + + +
+Implementation + + +
public fun get_coin_scaling_factor(): u64 {
+   COIN_SCALING_FACTOR
+}
+
+ + +
@@ -321,14 +362,14 @@ Get the constants for the current network
fun get_constants(): GlobalConstants {
-  let coin_scale = 1000000; // Diem::scaling_factor<GAS::T>();
-  assert(coin_scale == Diem::scaling_factor<GAS::GAS>(), Errors::invalid_argument(070001));
+  // let coin_scale = 1000000; // Diem::scaling_factor<GAS::T>();
+  assert(COIN_SCALING_FACTOR == Diem::scaling_factor<GAS::GAS>(), Errors::invalid_argument(070001));
 
   if (Testnet::is_testnet()) {
     return GlobalConstants {
       epoch_length: 60, // seconds
       max_validators_per_set: 100,
-      subsidy_ceiling_gas: 296 * coin_scale,
+      subsidy_ceiling_gas: 296 * COIN_SCALING_FACTOR,
       vdf_difficulty: 100,
       epoch_mining_thres_lower: 1,
       epoch_mining_thres_upper: 1000, // upper bound unlimited
@@ -338,28 +379,28 @@ Get the constants for the current network
 
   if (StagingNet::is_staging_net()) {
     return GlobalConstants {
-      epoch_length: 60 * 40, // 20 mins, enough for a hard miner proof.
+      epoch_length: 60 * 40, // 40 mins, enough for a hard miner proof.
       max_validators_per_set: 100,
-      subsidy_ceiling_gas: 8640000 * coin_scale,
-      vdf_difficulty: 5000000,
+      subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR,
+      vdf_difficulty: 120000000,
       epoch_mining_thres_lower: 1,
       epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
       epoch_slow_wallet_unlock: 10000000,
     }
   } else {
     return GlobalConstants {
-      epoch_length: 60 * 60 * 24, // approx 24 hours at 1.4 blocks/sec
+      epoch_length: 60 * 60 * 24, // approx 24 hours at 1.4 vdf_proofs/sec
       max_validators_per_set: 100, // max expected for BFT limits.
       // See DiemVMConfig for gas constants:
       // Target max gas units per transaction 100000000
       // target max block time: 2 secs
       // target transaction per sec max gas: 20
       // uses "scaled representation", since there are no decimals.
-      subsidy_ceiling_gas: 8640000 * coin_scale, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value.
-      vdf_difficulty: 5000000, // FYI approx 10 mins per proof on 2020 macbook pro 2.5 ghz quadcore
+      subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value.
+      vdf_difficulty: 120000000, // FYI approx 30 mins per proof on 2020 macbook pro 2.5 ghz quadcore
       epoch_mining_thres_lower: 7, // NOTE: bootstrapping, allowance for operator error.
       epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
-      epoch_slow_wallet_unlock: 1000 * coin_scale, // approx 10 years for largest accounts in genesis.
+      epoch_slow_wallet_unlock: 1000 * COIN_SCALING_FACTOR, // approx 10 years for largest accounts in genesis.
     }
   }
 }
diff --git a/language/diem-framework/modules/doc/ol_account.md b/language/diem-framework/modules/doc/ol_account.md
index 20c3691ddf..5897e721e3 100644
--- a/language/diem-framework/modules/doc/ol_account.md
+++ b/language/diem-framework/modules/doc/ol_account.md
@@ -5,17 +5,58 @@
 
 
 
+-  [Function `create_user_by_coin_tx`](#0x1_AccountScripts_create_user_by_coin_tx)
 -  [Function `create_acc_user`](#0x1_AccountScripts_create_acc_user)
 -  [Function `create_acc_val`](#0x1_AccountScripts_create_acc_val)
 
 
 
use 0x1::DiemAccount;
 use 0x1::GAS;
+use 0x1::Globals;
 use 0x1::ValidatorConfig;
 
+ + +## Function `create_user_by_coin_tx` + + + +
public(script) fun create_user_by_coin_tx(sender: signer, account: address, authkey_prefix: vector<u8>, unscaled_value: u64)
+
+ + + +
+Implementation + + +
public(script) fun create_user_by_coin_tx(
+    sender: signer,
+    account: address,
+    authkey_prefix: vector<u8>,
+    unscaled_value: u64,
+) {
+    // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR.
+    let value = unscaled_value * Globals::get_coin_scaling_factor();
+    let new_account_address = DiemAccount::create_user_account_with_coin(
+        &sender,
+        account,
+        authkey_prefix,
+        value,
+    );
+
+    // Check the account exists and the balance is 0
+    assert(DiemAccount::balance<GAS>(new_account_address) > 0, 01);
+}
+
+ + + +
+ ## Function `create_acc_user` diff --git a/language/diem-framework/modules/doc/ol_transfer.md b/language/diem-framework/modules/doc/ol_transfer.md new file mode 100644 index 0000000000..f0b9400e5e --- /dev/null +++ b/language/diem-framework/modules/doc/ol_transfer.md @@ -0,0 +1,62 @@ + + + +# Module `0x1::TransferScripts` + + + +- [Function `balance_transfer`](#0x1_TransferScripts_balance_transfer) + + +
use 0x1::DiemAccount;
+use 0x1::GAS;
+use 0x1::Globals;
+use 0x1::Signer;
+
+ + + + + +## Function `balance_transfer` + + + +
public(script) fun balance_transfer(sender: signer, destination: address, unscaled_value: u64)
+
+ + + +
+Implementation + + +
public(script) fun balance_transfer(
+    sender: signer,
+    destination: address,
+    unscaled_value: u64,
+) {
+    // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR.
+    let value = unscaled_value * Globals::get_coin_scaling_factor();
+    let sender_addr = Signer::address_of(&sender);
+    let sender_balance_pre = DiemAccount::balance<GAS>(sender_addr);
+    let destination_balance_pre = DiemAccount::balance<GAS>(destination);
+
+    let with_cap = DiemAccount::extract_withdraw_capability(&sender);
+    DiemAccount::pay_from<GAS>(&with_cap, destination, value, b"balance_transfer", b"");
+    DiemAccount::restore_withdraw_capability(with_cap);
+
+    assert(DiemAccount::balance<GAS>(destination) > destination_balance_pre, 01);
+    assert(DiemAccount::balance<GAS>(sender_addr) < sender_balance_pre, 02);
+}
+
+ + + +
+ + +[//]: # ("File containing references which can be used from documentation") +[ACCESS_CONTROL]: https://github.com/diem/dip/blob/main/dips/dip-2.md +[ROLE]: https://github.com/diem/dip/blob/main/dips/dip-2.md#roles +[PERMISSION]: https://github.com/diem/dip/blob/main/dips/dip-2.md#permissions diff --git a/language/diem-framework/modules/doc/overview.md b/language/diem-framework/modules/doc/overview.md index 3e60a3118f..dc30e0f1f3 100644 --- a/language/diem-framework/modules/doc/overview.md +++ b/language/diem-framework/modules/doc/overview.md @@ -156,6 +156,7 @@ The Move modules in the Diem Framework can be bucketed in to a couple categories - [`0x1::TowerState`](TowerState.md#0x1_TowerState) - [`0x1::TowerStateScripts`](ol_miner_state.md#0x1_TowerStateScripts) - [`0x1::TransactionFee`](TransactionFee.md#0x1_TransactionFee) +- [`0x1::TransferScripts`](ol_transfer.md#0x1_TransferScripts) - [`0x1::TreasuryComplianceScripts`](TreasuryComplianceScripts.md#0x1_TreasuryComplianceScripts) - [`0x1::Upgrade`](Upgrade.md#0x1_Upgrade) - [`0x1::VASP`](VASP.md#0x1_VASP) diff --git a/language/diem-framework/releases/artifacts/current/docs/modules/DiemAccount.md b/language/diem-framework/releases/artifacts/current/docs/modules/DiemAccount.md index acdc143959..9811746a0a 100644 --- a/language/diem-framework/releases/artifacts/current/docs/modules/DiemAccount.md +++ b/language/diem-framework/releases/artifacts/current/docs/modules/DiemAccount.md @@ -32,6 +32,7 @@ before and after every transaction. - [Function `initialize_escrow_root`](#0x1_DiemAccount_initialize_escrow_root) - [Function `initialize`](#0x1_DiemAccount_initialize) - [Function `create_user_account_with_proof`](#0x1_DiemAccount_create_user_account_with_proof) +- [Function `create_user_account_with_coin`](#0x1_DiemAccount_create_user_account_with_coin) - [Function `create_validator_account_with_proof`](#0x1_DiemAccount_create_validator_account_with_proof) - [Function `upgrade_validator_account_with_proof`](#0x1_DiemAccount_upgrade_validator_account_with_proof) - [Function `has_published_account_limits`](#0x1_DiemAccount_has_published_account_limits) @@ -804,6 +805,15 @@ Tried to add a balance in a currency that this account already has + + + + +
const EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN: u64 = 120125;
+
+ + + An account cannot be created at the reserved core code address of 0x1 @@ -1406,7 +1416,7 @@ Initialize this module. This is only callable from genesis. add_currencies_for_account<GAS>(&new_signer, false); make_account(new_signer, auth_key_prefix); - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Init the miner state // this verifies the VDF proof, which we use to rate limit account creation. // account will not be created if this step fails. @@ -1419,6 +1429,44 @@ Initialize this module. This is only callable from genesis. + + + + +## Function `create_user_account_with_coin` + + + +
public fun create_user_account_with_coin(sender: &signer, new_account: address, new_account_authkey_prefix: vector<u8>, value: u64): address
+
+ + + +
+Implementation + + +
public fun create_user_account_with_coin(
+    sender: &signer,
+    new_account: address,
+    new_account_authkey_prefix: vector<u8>,
+    value: u64,
+):address acquires AccountOperationsCapability, Balance, CumulativeDeposits, DiemAccount {
+
+    // let (new_account_address, auth_key_prefix) = VDF::extract_address_from_challenge(challenge);
+    let new_signer = create_signer(new_account);
+    Roles::new_user_role_with_proof(&new_signer);
+    Event::publish_generator(&new_signer);
+    add_currencies_for_account<GAS>(&new_signer, false);
+    make_account(new_signer, new_account_authkey_prefix);
+
+    onboarding_gas_transfer<GAS>(sender, new_account, value);
+    new_account
+}
+
+ + +
@@ -1519,9 +1567,9 @@ Initialize this module. This is only callable from genesis. // Transfer for owner - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer<GAS>(sender, op_address); + onboarding_gas_transfer<GAS>(sender, op_address, BOOTSTRAP_COIN_VALUE); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -1638,9 +1686,9 @@ print(&509); print(&510); // the miner who is upgrading may have coins, but better safe... // Transfer for owner - onboarding_gas_transfer<GAS>(sender, new_account_address); + onboarding_gas_transfer<GAS>(sender, new_account_address, BOOTSTRAP_COIN_VALUE); // Transfer for operator as well - onboarding_gas_transfer<GAS>(sender, op_address); + onboarding_gas_transfer<GAS>(sender, op_address, BOOTSTRAP_COIN_VALUE); print(&510); let new_signer = create_signer(new_account_address); set_slow(&new_signer); @@ -3024,7 +3072,7 @@ subject to the dual attestation protocol -
fun onboarding_gas_transfer<Token: store>(payer_sig: &signer, payee: address)
+
fun onboarding_gas_transfer<Token: store>(payer_sig: &signer, payee: address, value: u64)
 
@@ -3035,19 +3083,27 @@ subject to the dual attestation protocol
fun onboarding_gas_transfer<Token: store>(
     payer_sig: &signer,
-    payee: address
+    payee: address,
+    value: u64,
 ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits { //////// 0L ////////
     let payer_addr = Signer::address_of(payer_sig);
     let account_balance = borrow_global_mut<Balance<Token>>(payer_addr);
     let balance_coin = &mut account_balance.coin;
+
+    // value needs to be greater than boostrapping value
+    assert(
+        value >= BOOTSTRAP_COIN_VALUE,
+        Errors::limit_exceeded(EBELOW_MINIMUM_VALUE_BOOTSTRAP_COIN)
+    );
+
     // Doubly check balance exists.
     assert(
-        Diem::value(balance_coin) > BOOTSTRAP_COIN_VALUE,
+        Diem::value(balance_coin) > value,
         Errors::limit_exceeded(EINSUFFICIENT_BALANCE)
     );
     // Should abort if the
     let metadata = b"onboarding coin transfer";
-    let coin_to_deposit = Diem::withdraw(balance_coin, BOOTSTRAP_COIN_VALUE);
+    let coin_to_deposit = Diem::withdraw(balance_coin, value);
     deposit<Token>(
         payer_addr,
         payee,
@@ -3083,9 +3139,7 @@ subject to the dual attestation protocol
   oper: address,
 ) acquires DiemAccount, Balance, AccountOperationsCapability, CumulativeDeposits {
   CoreAddresses::assert_vm(vm);
-  onboarding_gas_transfer<GAS>(owner_sig, oper);
-
-
+  onboarding_gas_transfer<GAS>(owner_sig, oper, BOOTSTRAP_COIN_VALUE);
 }
 
diff --git a/language/diem-framework/releases/artifacts/current/docs/modules/Globals.md b/language/diem-framework/releases/artifacts/current/docs/modules/Globals.md index 5363b0c82c..7e7deb41ea 100644 --- a/language/diem-framework/releases/artifacts/current/docs/modules/Globals.md +++ b/language/diem-framework/releases/artifacts/current/docs/modules/Globals.md @@ -13,8 +13,10 @@ This module provides global variables and constants that have no specific owner - [Summary](#@Summary_0) - [Struct `GlobalConstants`](#0x1_Globals_GlobalConstants) +- [Constants](#@Constants_1) - [Function `get_epoch_length`](#0x1_Globals_get_epoch_length) - [Function `get_max_validators_per_set`](#0x1_Globals_get_max_validators_per_set) +- [Function `get_coin_scaling_factor`](#0x1_Globals_get_coin_scaling_factor) - [Function `get_subsidy_ceiling_gas`](#0x1_Globals_get_subsidy_ceiling_gas) - [Function `get_vdf_difficulty`](#0x1_Globals_get_vdf_difficulty) - [Function `get_vdf_security`](#0x1_Globals_get_vdf_security) @@ -104,6 +106,20 @@ epoch by a miner to remain compliant + + +## Constants + + + + + + +
const COIN_SCALING_FACTOR: u64 = 1000000;
+
+ + + ## Function `get_epoch_length` @@ -152,6 +168,31 @@ Get max validator per epoch + + + + +## Function `get_coin_scaling_factor` + +Get the epoch length + + +
public fun get_coin_scaling_factor(): u64
+
+ + + +
+Implementation + + +
public fun get_coin_scaling_factor(): u64 {
+   COIN_SCALING_FACTOR
+}
+
+ + +
@@ -321,14 +362,14 @@ Get the constants for the current network
fun get_constants(): GlobalConstants {
-  let coin_scale = 1000000; // Diem::scaling_factor<GAS::T>();
-  assert(coin_scale == Diem::scaling_factor<GAS::GAS>(), Errors::invalid_argument(070001));
+  // let coin_scale = 1000000; // Diem::scaling_factor<GAS::T>();
+  assert(COIN_SCALING_FACTOR == Diem::scaling_factor<GAS::GAS>(), Errors::invalid_argument(070001));
 
   if (Testnet::is_testnet()) {
     return GlobalConstants {
       epoch_length: 60, // seconds
       max_validators_per_set: 100,
-      subsidy_ceiling_gas: 296 * coin_scale,
+      subsidy_ceiling_gas: 296 * COIN_SCALING_FACTOR,
       vdf_difficulty: 100,
       epoch_mining_thres_lower: 1,
       epoch_mining_thres_upper: 1000, // upper bound unlimited
@@ -338,28 +379,28 @@ Get the constants for the current network
 
   if (StagingNet::is_staging_net()) {
     return GlobalConstants {
-      epoch_length: 60 * 40, // 20 mins, enough for a hard miner proof.
+      epoch_length: 60 * 40, // 40 mins, enough for a hard miner proof.
       max_validators_per_set: 100,
-      subsidy_ceiling_gas: 8640000 * coin_scale,
-      vdf_difficulty: 5000000,
+      subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR,
+      vdf_difficulty: 120000000,
       epoch_mining_thres_lower: 1,
       epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
       epoch_slow_wallet_unlock: 10000000,
     }
   } else {
     return GlobalConstants {
-      epoch_length: 60 * 60 * 24, // approx 24 hours at 1.4 blocks/sec
+      epoch_length: 60 * 60 * 24, // approx 24 hours at 1.4 vdf_proofs/sec
       max_validators_per_set: 100, // max expected for BFT limits.
       // See DiemVMConfig for gas constants:
       // Target max gas units per transaction 100000000
       // target max block time: 2 secs
       // target transaction per sec max gas: 20
       // uses "scaled representation", since there are no decimals.
-      subsidy_ceiling_gas: 8640000 * coin_scale, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value.
-      vdf_difficulty: 5000000, // FYI approx 10 mins per proof on 2020 macbook pro 2.5 ghz quadcore
+      subsidy_ceiling_gas: 8640000 * COIN_SCALING_FACTOR, // subsidy amount assumes 24 hour epoch lengths. Also needs to be adjusted for coin_scale the onchain representation of human readable value.
+      vdf_difficulty: 120000000, // FYI approx 30 mins per proof on 2020 macbook pro 2.5 ghz quadcore
       epoch_mining_thres_lower: 7, // NOTE: bootstrapping, allowance for operator error.
       epoch_mining_thres_upper: 72, // upper bound enforced at 20 mins per proof.
-      epoch_slow_wallet_unlock: 1000 * coin_scale, // approx 10 years for largest accounts in genesis.
+      epoch_slow_wallet_unlock: 1000 * COIN_SCALING_FACTOR, // approx 10 years for largest accounts in genesis.
     }
   }
 }
diff --git a/language/diem-framework/releases/artifacts/current/docs/modules/ol_account.md b/language/diem-framework/releases/artifacts/current/docs/modules/ol_account.md
index 20c3691ddf..5897e721e3 100644
--- a/language/diem-framework/releases/artifacts/current/docs/modules/ol_account.md
+++ b/language/diem-framework/releases/artifacts/current/docs/modules/ol_account.md
@@ -5,17 +5,58 @@
 
 
 
+-  [Function `create_user_by_coin_tx`](#0x1_AccountScripts_create_user_by_coin_tx)
 -  [Function `create_acc_user`](#0x1_AccountScripts_create_acc_user)
 -  [Function `create_acc_val`](#0x1_AccountScripts_create_acc_val)
 
 
 
use 0x1::DiemAccount;
 use 0x1::GAS;
+use 0x1::Globals;
 use 0x1::ValidatorConfig;
 
+ + +## Function `create_user_by_coin_tx` + + + +
public(script) fun create_user_by_coin_tx(sender: signer, account: address, authkey_prefix: vector<u8>, unscaled_value: u64)
+
+ + + +
+Implementation + + +
public(script) fun create_user_by_coin_tx(
+    sender: signer,
+    account: address,
+    authkey_prefix: vector<u8>,
+    unscaled_value: u64,
+) {
+    // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR.
+    let value = unscaled_value * Globals::get_coin_scaling_factor();
+    let new_account_address = DiemAccount::create_user_account_with_coin(
+        &sender,
+        account,
+        authkey_prefix,
+        value,
+    );
+
+    // Check the account exists and the balance is 0
+    assert(DiemAccount::balance<GAS>(new_account_address) > 0, 01);
+}
+
+ + + +
+ ## Function `create_acc_user` diff --git a/language/diem-framework/releases/artifacts/current/docs/modules/ol_transfer.md b/language/diem-framework/releases/artifacts/current/docs/modules/ol_transfer.md new file mode 100644 index 0000000000..f0b9400e5e --- /dev/null +++ b/language/diem-framework/releases/artifacts/current/docs/modules/ol_transfer.md @@ -0,0 +1,62 @@ + + + +# Module `0x1::TransferScripts` + + + +- [Function `balance_transfer`](#0x1_TransferScripts_balance_transfer) + + +
use 0x1::DiemAccount;
+use 0x1::GAS;
+use 0x1::Globals;
+use 0x1::Signer;
+
+ + + + + +## Function `balance_transfer` + + + +
public(script) fun balance_transfer(sender: signer, destination: address, unscaled_value: u64)
+
+ + + +
+Implementation + + +
public(script) fun balance_transfer(
+    sender: signer,
+    destination: address,
+    unscaled_value: u64,
+) {
+    // IMPORTANT: the human representation of a value is unscaled. The user which expects to send 10 coins, will input that as an unscaled_value. This script converts it to the Move internal scale by multiplying by COIN_SCALING_FACTOR.
+    let value = unscaled_value * Globals::get_coin_scaling_factor();
+    let sender_addr = Signer::address_of(&sender);
+    let sender_balance_pre = DiemAccount::balance<GAS>(sender_addr);
+    let destination_balance_pre = DiemAccount::balance<GAS>(destination);
+
+    let with_cap = DiemAccount::extract_withdraw_capability(&sender);
+    DiemAccount::pay_from<GAS>(&with_cap, destination, value, b"balance_transfer", b"");
+    DiemAccount::restore_withdraw_capability(with_cap);
+
+    assert(DiemAccount::balance<GAS>(destination) > destination_balance_pre, 01);
+    assert(DiemAccount::balance<GAS>(sender_addr) < sender_balance_pre, 02);
+}
+
+ + + +
+ + +[//]: # ("File containing references which can be used from documentation") +[ACCESS_CONTROL]: https://github.com/diem/dip/blob/main/dips/dip-2.md +[ROLE]: https://github.com/diem/dip/blob/main/dips/dip-2.md#roles +[PERMISSION]: https://github.com/diem/dip/blob/main/dips/dip-2.md#permissions diff --git a/language/diem-framework/releases/artifacts/current/docs/modules/overview.md b/language/diem-framework/releases/artifacts/current/docs/modules/overview.md index 3e60a3118f..dc30e0f1f3 100644 --- a/language/diem-framework/releases/artifacts/current/docs/modules/overview.md +++ b/language/diem-framework/releases/artifacts/current/docs/modules/overview.md @@ -156,6 +156,7 @@ The Move modules in the Diem Framework can be bucketed in to a couple categories - [`0x1::TowerState`](TowerState.md#0x1_TowerState) - [`0x1::TowerStateScripts`](ol_miner_state.md#0x1_TowerStateScripts) - [`0x1::TransactionFee`](TransactionFee.md#0x1_TransactionFee) +- [`0x1::TransferScripts`](ol_transfer.md#0x1_TransferScripts) - [`0x1::TreasuryComplianceScripts`](TreasuryComplianceScripts.md#0x1_TreasuryComplianceScripts) - [`0x1::Upgrade`](Upgrade.md#0x1_Upgrade) - [`0x1::VASP`](VASP.md#0x1_VASP) diff --git a/language/diem-framework/releases/artifacts/current/error_description/error_description.errmap b/language/diem-framework/releases/artifacts/current/error_description/error_description.errmap index 3e7cd15c1b..3a54c91b96 100644 Binary files a/language/diem-framework/releases/artifacts/current/error_description/error_description.errmap and b/language/diem-framework/releases/artifacts/current/error_description/error_description.errmap differ diff --git a/language/diem-framework/releases/artifacts/current/modules/026_Globals.mv b/language/diem-framework/releases/artifacts/current/modules/026_Globals.mv index 21a56e28f9..b895b01dee 100644 Binary files a/language/diem-framework/releases/artifacts/current/modules/026_Globals.mv and b/language/diem-framework/releases/artifacts/current/modules/026_Globals.mv differ diff --git a/language/diem-framework/releases/artifacts/current/modules/044_DiemAccount.mv b/language/diem-framework/releases/artifacts/current/modules/044_DiemAccount.mv index b902a64275..377c5e00e5 100644 Binary files a/language/diem-framework/releases/artifacts/current/modules/044_DiemAccount.mv and b/language/diem-framework/releases/artifacts/current/modules/044_DiemAccount.mv differ diff --git a/language/diem-framework/releases/artifacts/current/modules/050_AccountScripts.mv b/language/diem-framework/releases/artifacts/current/modules/050_AccountScripts.mv index 5c5ded6b99..cae8d138e3 100644 Binary files a/language/diem-framework/releases/artifacts/current/modules/050_AccountScripts.mv and b/language/diem-framework/releases/artifacts/current/modules/050_AccountScripts.mv differ diff --git a/language/diem-framework/releases/artifacts/current/modules/077_TransferScripts.mv b/language/diem-framework/releases/artifacts/current/modules/077_TransferScripts.mv new file mode 100644 index 0000000000..3b402b2c7c Binary files /dev/null and b/language/diem-framework/releases/artifacts/current/modules/077_TransferScripts.mv differ diff --git a/language/diem-framework/releases/artifacts/current/modules/077_TreasuryComplianceScripts.mv b/language/diem-framework/releases/artifacts/current/modules/078_TreasuryComplianceScripts.mv similarity index 100% rename from language/diem-framework/releases/artifacts/current/modules/077_TreasuryComplianceScripts.mv rename to language/diem-framework/releases/artifacts/current/modules/078_TreasuryComplianceScripts.mv diff --git a/language/diem-framework/releases/artifacts/current/modules/078_ValidatorAdministrationScripts.mv b/language/diem-framework/releases/artifacts/current/modules/079_ValidatorAdministrationScripts.mv similarity index 100% rename from language/diem-framework/releases/artifacts/current/modules/078_ValidatorAdministrationScripts.mv rename to language/diem-framework/releases/artifacts/current/modules/079_ValidatorAdministrationScripts.mv diff --git a/language/diem-framework/releases/artifacts/current/modules/079_ValidatorScripts.mv b/language/diem-framework/releases/artifacts/current/modules/080_ValidatorScripts.mv similarity index 100% rename from language/diem-framework/releases/artifacts/current/modules/079_ValidatorScripts.mv rename to language/diem-framework/releases/artifacts/current/modules/080_ValidatorScripts.mv diff --git a/language/diem-framework/releases/artifacts/current/modules/080_WalletScripts.mv b/language/diem-framework/releases/artifacts/current/modules/081_WalletScripts.mv similarity index 100% rename from language/diem-framework/releases/artifacts/current/modules/080_WalletScripts.mv rename to language/diem-framework/releases/artifacts/current/modules/081_WalletScripts.mv diff --git a/language/diem-framework/releases/artifacts/current/script_abis/ol_account/create_user_by_coin_tx.abi b/language/diem-framework/releases/artifacts/current/script_abis/ol_account/create_user_by_coin_tx.abi new file mode 100644 index 0000000000..276a97de60 Binary files /dev/null and b/language/diem-framework/releases/artifacts/current/script_abis/ol_account/create_user_by_coin_tx.abi differ diff --git a/language/diem-framework/releases/artifacts/current/script_abis/ol_transfer/balance_transfer.abi b/language/diem-framework/releases/artifacts/current/script_abis/ol_transfer/balance_transfer.abi new file mode 100644 index 0000000000..b28ce357f4 Binary files /dev/null and b/language/diem-framework/releases/artifacts/current/script_abis/ol_transfer/balance_transfer.abi differ diff --git a/language/diem-framework/releases/artifacts/current/transaction_script_builder.rs b/language/diem-framework/releases/artifacts/current/transaction_script_builder.rs index a0a3e2aacd..02c405fb4b 100644 --- a/language/diem-framework/releases/artifacts/current/transaction_script_builder.rs +++ b/language/diem-framework/releases/artifacts/current/transaction_script_builder.rs @@ -1611,6 +1611,11 @@ pub enum ScriptFunctionCall { AutopayEnable {}, + BalanceTransfer { + destination: AccountAddress, + unscaled_value: u64, + }, + /// # Summary /// Burns the transaction fees collected in the `CoinType` currency so that the /// Diem association may reclaim the backing coins off-chain. May only be sent @@ -2020,6 +2025,12 @@ pub enum ScriptFunctionCall { /// * `Script::rotate_authentication_key_with_recovery_address` CreateRecoveryAddress {}, + CreateUserByCoinTx { + account: AccountAddress, + authkey_prefix: Bytes, + unscaled_value: u64, + }, + /// # Summary /// Creates a Validator account. This transaction can only be sent by the Diem /// Root account. @@ -3497,6 +3508,10 @@ impl ScriptFunctionCall { ), AutopayDisable {} => encode_autopay_disable_script_function(), AutopayEnable {} => encode_autopay_enable_script_function(), + BalanceTransfer { + destination, + unscaled_value, + } => encode_balance_transfer_script_function(destination, unscaled_value), BurnTxnFees { coin_type } => encode_burn_txn_fees_script_function(coin_type), BurnWithAmount { token, @@ -3590,6 +3605,15 @@ impl ScriptFunctionCall { add_all_currencies, ), CreateRecoveryAddress {} => encode_create_recovery_address_script_function(), + CreateUserByCoinTx { + account, + authkey_prefix, + unscaled_value, + } => encode_create_user_by_coin_tx_script_function( + account, + authkey_prefix, + unscaled_value, + ), CreateValidatorAccount { sliding_nonce, new_account_address, @@ -4097,6 +4121,24 @@ pub fn encode_autopay_enable_script_function() -> TransactionPayload { )) } +pub fn encode_balance_transfer_script_function( + destination: AccountAddress, + unscaled_value: u64, +) -> TransactionPayload { + TransactionPayload::ScriptFunction(ScriptFunction::new( + ModuleId::new( + AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ident_str!("TransferScripts").to_owned(), + ), + ident_str!("balance_transfer").to_owned(), + vec![], + vec![ + bcs::to_bytes(&destination).unwrap(), + bcs::to_bytes(&unscaled_value).unwrap(), + ], + )) +} + /// # Summary /// Burns the transaction fees collected in the `CoinType` currency so that the /// Diem association may reclaim the backing coins off-chain. May only be sent @@ -4645,6 +4687,26 @@ pub fn encode_create_recovery_address_script_function() -> TransactionPayload { )) } +pub fn encode_create_user_by_coin_tx_script_function( + account: AccountAddress, + authkey_prefix: Vec, + unscaled_value: u64, +) -> TransactionPayload { + TransactionPayload::ScriptFunction(ScriptFunction::new( + ModuleId::new( + AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ident_str!("AccountScripts").to_owned(), + ), + ident_str!("create_user_by_coin_tx").to_owned(), + vec![], + vec![ + bcs::to_bytes(&account).unwrap(), + bcs::to_bytes(&authkey_prefix).unwrap(), + bcs::to_bytes(&unscaled_value).unwrap(), + ], + )) +} + /// # Summary /// Creates a Validator account. This transaction can only be sent by the Diem /// Root account. @@ -8065,6 +8127,19 @@ fn decode_autopay_enable_script_function( } } +fn decode_balance_transfer_script_function( + payload: &TransactionPayload, +) -> Option { + if let TransactionPayload::ScriptFunction(script) = payload { + Some(ScriptFunctionCall::BalanceTransfer { + destination: bcs::from_bytes(script.args().get(0)?).ok()?, + unscaled_value: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + fn decode_burn_txn_fees_script_function( payload: &TransactionPayload, ) -> Option { @@ -8213,6 +8288,20 @@ fn decode_create_recovery_address_script_function( } } +fn decode_create_user_by_coin_tx_script_function( + payload: &TransactionPayload, +) -> Option { + if let TransactionPayload::ScriptFunction(script) = payload { + Some(ScriptFunctionCall::CreateUserByCoinTx { + account: bcs::from_bytes(script.args().get(0)?).ok()?, + authkey_prefix: bcs::from_bytes(script.args().get(1)?).ok()?, + unscaled_value: bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } +} + fn decode_create_validator_account_script_function( payload: &TransactionPayload, ) -> Option { @@ -9166,6 +9255,10 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy String { - match env::var("NODE_ENV") { - Ok(val) => val, - _ => "test".to_string(), // default to "test" if not set - } -} + //////// 0L //////// fn initialize_testnet(session: &mut Session, log_context: &impl LogContext) { let diem_root_address = account_config::diem_root_address(); - let mut module_name = "Testnet"; - if get_env() == "stage" { - module_name = "StagingNet"; + + + let genesis_env = env::var("NODE_ENV").unwrap(); + println!("Initializing with env: {}", genesis_env); + + //////// 0L //////// + let module_name = match genesis_env.as_ref() { + "test" => "Testnet", + "stage" => "StagingNet", + _ => { + println!("ERROR: env is ambiguous. Are you starting a test or staging network? Found env: {}", &genesis_env); + exit(1); + }, }; + exec_function( session, log_context, diff --git a/ol/documentation/genesis/genesis_registration.md b/ol/documentation/genesis/genesis_registration.md index 16b9d7b61d..71216243f1 100644 --- a/ol/documentation/genesis/genesis_registration.md +++ b/ol/documentation/genesis/genesis_registration.md @@ -68,9 +68,11 @@ In your ~/.0L/ folder you will want to see: - /github_token.txt - /autopay_batch.json -There is a DANGEROUS helper that will do this for you. 1) backup the files, 2) wipe ~/.0L and 3) sync your blocks and token back. You will be prompted for Y/N at each step. +There are some makefiles which can help 1) backup the files, 2) wipe ~/.0L and 3) sync your blocks and token back. You will be prompted for Y/N at each step. ``` -make danger-delete-all +make backup +# if you your backup is called /0L_backup/, then you can restore with: +make danger-restore ``` # Registration diff --git a/ol/onboard/src/commands/keygen_cmd.rs b/ol/onboard/src/commands/keygen_cmd.rs index 6833354c9c..551985c030 100644 --- a/ol/onboard/src/commands/keygen_cmd.rs +++ b/ol/onboard/src/commands/keygen_cmd.rs @@ -6,11 +6,23 @@ use abscissa_core::{Command, Options, Runnable}; use ol_keys::wallet; /// `keygen` subcommand #[derive(Command, Debug, Default, Options)] -pub struct KeygenCmd {} +pub struct KeygenCmd { + #[options(short="w", help = "who am I?")] + whoami: bool, +} impl Runnable for KeygenCmd { fn run(&self) { - wallet::keygen(); + if self.whoami { + let (auth, addr, wallet) = wallet::get_account_from_prompt(); + println!("\n0L ACCOUNT\n"); + println!("address: {}", addr); + println!("authentication key (for account creation): {}\n", auth); + + } else { + wallet::keygen(); + } + } } diff --git a/ol/onboard/src/commands/wizard_fork_cmd.rs b/ol/onboard/src/commands/wizard_fork_cmd.rs index f1c6727a9f..87ebf512ba 100644 --- a/ol/onboard/src/commands/wizard_fork_cmd.rs +++ b/ol/onboard/src/commands/wizard_fork_cmd.rs @@ -65,7 +65,7 @@ impl Runnable for ForkCmd { status_info!("\nValidator Config Wizard.", "Next you'll enter your mnemonic and some other info to configure your validator node and on-chain account. If you haven't yet generated keys, run the standalone keygen tool with 'onboard keygen'."); if !self.skip_mining { - println!("\nYour first 0L proof-of-work will be mined now. Expect this to take up to 15 minutes on modern CPUs.\n"); + println!("\nYour first 0L proof-of-work will be mined now. Expect this take at least 30 minutes on modern CPUs.\n"); } let entry_args = entrypoint::get_args(); diff --git a/ol/onboard/src/commands/wizard_val_cmd.rs b/ol/onboard/src/commands/wizard_val_cmd.rs index 2e1f7cf130..740967a0d8 100644 --- a/ol/onboard/src/commands/wizard_val_cmd.rs +++ b/ol/onboard/src/commands/wizard_val_cmd.rs @@ -70,7 +70,7 @@ impl Runnable for ValWizardCmd { ); if !self.skip_mining { - println!("\nYour first 0L proof-of-work will be mined now. Expect this to take up to 15 minutes on modern CPUs.\n"); + println!("\nYour first 0L proof-of-work will be mined now. Expect this take at least 30 minutes on modern CPUs.\n"); } let entry_args = entrypoint::get_args(); diff --git a/ol/tower/src/proof.rs b/ol/tower/src/proof.rs index 2ca7d57844..099a574bb1 100644 --- a/ol/tower/src/proof.rs +++ b/ol/tower/src/proof.rs @@ -15,6 +15,7 @@ use std::{ }; use txs::submit_tx::TxParams; +/// name of the proof files pub const FILENAME: &str = "proof"; // writes a JSON file with the first vdf proof diff --git a/ol/txs/src/commands.rs b/ol/txs/src/commands.rs index c78f043fc0..50b8d33416 100644 --- a/ol/txs/src/commands.rs +++ b/ol/txs/src/commands.rs @@ -10,17 +10,18 @@ //! See the `impl Configurable` below for how to specify the path to the //! application's configuration file. -mod create_account_cmd; -mod create_validator_cmd; -mod oracle_upgrade_cmd; -mod version_cmd; pub mod autopay_batch_cmd; pub mod demo_cmd; +pub mod create_account_cmd; +pub mod transfer_cmd; mod relay_cmd; mod valset_cmd; mod autopay_cmd; mod wallet_cmd; mod authkey_cmd; +mod create_validator_cmd; +mod oracle_upgrade_cmd; +mod version_cmd; use abscissa_core::{Command, Configurable, Help, Options, Runnable}; use ol::commands::CONFIG_FILE; @@ -37,7 +38,8 @@ use self::{ relay_cmd::RelayCmd, valset_cmd::ValSetCmd, wallet_cmd::WalletCmd, - authkey_cmd::AuthkeyCmd, + authkey_cmd::AuthkeyCmd, + transfer_cmd::TransferCmd, }; use std::path::PathBuf; @@ -52,6 +54,10 @@ pub enum TxsCmd { #[options(help = "submit tx to create a validator from account.json file")] CreateValidator(CreateValidatorCmd), + /// Transfer balance between accounts + #[options(help = "rotate an account's authorization key")] + Transfer(TransferCmd), + /// The `oracle-upgrade` subcommand #[options(help = "submit an oracle transaction to upgrade stdlib")] OracleUpgrade(OracleUpgradeCmd), @@ -92,7 +98,7 @@ pub enum TxsCmd { /// The `authkey` subcommand to rotate an auth key (change mnemonic that controls address) #[options(help = "rotate an account's authorization key")] - Authkey(AuthkeyCmd), + Authkey(AuthkeyCmd), } /// This trait allows you to define how application configuration is loaded. diff --git a/ol/txs/src/commands/create_account_cmd.depr b/ol/txs/src/commands/create_account_cmd.depr new file mode 100644 index 0000000000..ff66890f67 --- /dev/null +++ b/ol/txs/src/commands/create_account_cmd.depr @@ -0,0 +1,61 @@ +//! `CreateAccount` subcommand + +#![allow(clippy::never_loop)] + +use abscissa_core::{Command, Options, Runnable}; +use ol_types::{account::UserConfigs, config::TxType}; +use crate::{entrypoint, submit_tx::{tx_params_wrapper, maybe_submit}}; +use diem_types::transaction::{TransactionPayload, authenticator::AuthenticationKey}; +use diem_transaction_builder::stdlib as transaction_builder; +use std::{fs, path::PathBuf, process::exit}; +use std::io::Read; +/// `CreateAccount` subcommand +#[derive(Command, Debug, Default, Options)] +pub struct CreateAccountCmd { + // TODO: deprecate creation of accounts with proof + #[options(short = "f", help = "path of account.json")] + account_json_path: Option, +} + +pub fn create_user_account_script_function(account_json_path: &str) -> TransactionPayload { + + if let Some(path) = account_json_path { + let mut json_string = String::new(); + let mut file = fs::File::open(account_json_path).expect("file should open read only"); + file.read_to_string(&mut json_string) + .unwrap_or_else(|err| panic!("Error while reading file: [{}]", err)); + + let user: UserConfigs = serde_json::from_str(&json_string).expect("could not parse json file"); + + transaction_builder::encode_create_acc_user_script_function( + user.block_zero.preimage.clone(), + user.block_zero.proof.clone(), + user.block_zero.difficulty(), + user.block_zero.security(), + ); + } + +} + +impl Runnable for CreateAccountCmd { + fn run(&self) { + let entry_args = entrypoint::get_args(); + let tx_params = tx_params_wrapper(TxType::Mgmt).unwrap(); + + match maybe_submit( + create_user_account_script_function(&self.account_json.unwrap().to_string()), + &tx_params, + entry_args.no_send, + entry_args.save_path, + ) { + Err(e) => { + println!( + "ERROR: could not submit account creation transaction, message: \n{:?}", + &e + ); + exit(1); + }, + _ => {} + } + } +} \ No newline at end of file diff --git a/ol/txs/src/commands/create_account_cmd.rs b/ol/txs/src/commands/create_account_cmd.rs index e583ac1a16..0a67ca3e6b 100644 --- a/ol/txs/src/commands/create_account_cmd.rs +++ b/ol/txs/src/commands/create_account_cmd.rs @@ -2,57 +2,58 @@ #![allow(clippy::never_loop)] +use crate::{ + entrypoint, + submit_tx::{maybe_submit, tx_params_wrapper}, +}; use abscissa_core::{Command, Options, Runnable}; -use ol_types::{account::UserConfigs, config::TxType}; -use crate::{entrypoint, submit_tx::{tx_params_wrapper, maybe_submit}}; -use diem_types::transaction::TransactionPayload; +use anyhow::Error; use diem_transaction_builder::stdlib as transaction_builder; -use std::{fs, path::PathBuf, process::exit}; -use std::io::Read; +use diem_types::transaction::{SignedTransaction, authenticator::AuthenticationKey}; +use ol_types::config::TxType; +use std::{path::PathBuf, process::exit}; /// `CreateAccount` subcommand #[derive(Command, Debug, Default, Options)] pub struct CreateAccountCmd { - #[options(short = "f", help = "path of account.json")] - account_json_path: PathBuf, + #[options(short = "a", help = "the new user's long address (authentication key)")] + authkey: String, + #[options(short = "c", help = "the amount of coins to send to new user")] + coins: u64, } -pub fn create_user_account_script_function(account_json_path: &str) -> TransactionPayload { - - let mut json_string = String::new(); - let mut file = fs::File::open(account_json_path).expect("file should open read only"); - file.read_to_string(&mut json_string) - .unwrap_or_else(|err| panic!("Error while reading file: [{}]", err)); - - let user: UserConfigs = serde_json::from_str(&json_string).expect("could not parse json file"); - - transaction_builder::encode_create_acc_user_script_function( - user.block_zero.preimage.clone(), - user.block_zero.proof.clone(), - user.block_zero.difficulty(), - user.block_zero.security(), - ) -} - -impl Runnable for CreateAccountCmd { +impl Runnable for CreateAccountCmd { fn run(&self) { let entry_args = entrypoint::get_args(); - let account_json = self.account_json_path.to_str().unwrap(); - let tx_params = tx_params_wrapper(TxType::Mgmt).unwrap(); - - match maybe_submit( - create_user_account_script_function(account_json), - &tx_params, - entry_args.no_send, - entry_args.save_path, - ) { + let authkey = match self.authkey.parse::(){ + Ok(a) => a, Err(e) => { - println!( - "ERROR: could not submit account creation transaction, message: \n{:?}", - &e - ); - exit(1); + println!("ERROR: could not parse this account address: {}, message: {}", self.authkey, &e.to_string()); + exit(1); }, - _ => {} - } + }; + + match create_from_auth_and_coin(authkey, self.coins, entry_args.no_send, entry_args.save_path) { + Ok(_) => println!("Success. Account created for authkey: {}", authkey), + Err(e) => { + println!("ERROR: could not create account, message: {}", &e.to_string()); + exit(1); + }, + } } +} + +/// create an account by sending coin to it +pub fn create_from_auth_and_coin(authkey: AuthenticationKey, coins: u64, no_send: bool, save_path: Option) -> Result{ + let tx_params = tx_params_wrapper(TxType::Mgmt).unwrap(); + + let account = authkey.derived_address(); + let prefix = authkey.prefix(); + // NOTE: coins here do not have the scaling factor. Rescaling is the responsibility of the Move script. See the script in ol_accounts.move for detail. + let script = transaction_builder::encode_create_user_by_coin_tx_script_function( + account, + prefix.to_vec(), + coins, + ); + + maybe_submit(script, &tx_params, no_send, save_path) } \ No newline at end of file diff --git a/ol/txs/src/commands/transfer_cmd.rs b/ol/txs/src/commands/transfer_cmd.rs new file mode 100644 index 0000000000..16adf10af4 --- /dev/null +++ b/ol/txs/src/commands/transfer_cmd.rs @@ -0,0 +1,56 @@ +//! `CreateAccount` subcommand + +#![allow(clippy::never_loop)] + +use crate::{ + entrypoint, + submit_tx::{maybe_submit, tx_params_wrapper}, +}; +use abscissa_core::{Command, Options, Runnable}; +use anyhow::Error; +use diem_transaction_builder::stdlib as transaction_builder; +use diem_types::{account_address::AccountAddress, transaction::SignedTransaction}; +use ol_types::config::TxType; +use std::{path::PathBuf, process::exit}; +/// `CreateAccount` subcommand +#[derive(Command, Debug, Default, Options)] +pub struct TransferCmd { + #[options(short = "a", help = "the new user's long address (authentication key)")] + destination_account: String, + #[options(short = "c", help = "the amount of coins to send to new user")] + coins: u64, +} + +impl Runnable for TransferCmd { + fn run(&self) { + let entry_args = entrypoint::get_args(); + let destination = match self.destination_account.parse::(){ + Ok(a) => a, + Err(e) => { + println!("ERROR: could not parse this account address: {}, message: {}", self.destination_account, &e.to_string()); + exit(1); + }, + }; + + match balance_transfer(destination, self.coins, entry_args.no_send, entry_args.save_path) { + Ok(_) => println!("Success. Balance transfer success: {}", self.destination_account), + Err(e) => { + println!("ERROR: could not create account, message: {}", &e.to_string()); + exit(1); + }, + } + } +} + +/// create an account by sending coin to it +pub fn balance_transfer(destination: AccountAddress, coins: u64, no_send: bool, save_path: Option) -> Result{ + let tx_params = tx_params_wrapper(TxType::Mgmt).unwrap(); + + // NOTE: coins here do not have the scaling factor. Rescaling is the responsibility of the Move script. See the script in ol_accounts.move for detail. + let script = transaction_builder::encode_balance_transfer_script_function( + destination, + coins, + ); + + maybe_submit(script, &tx_params, no_send, save_path) +} \ No newline at end of file diff --git a/ol/util/setup.sh b/ol/util/setup.sh index 9fa1da098b..8b8dbbac8e 100644 --- a/ol/util/setup.sh +++ b/ol/util/setup.sh @@ -3,6 +3,7 @@ # targeting ubuntu sudo apt update sudo apt install -y git vim zip unzip jq build-essential cmake clang llvm libgmp-dev secure-delete pkg-config libssl-dev lld + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y PATH="$HOME/.cargo/bin:$PATH" cargo install toml-cli PATH="$HOME/.cargo/bin:$PATH" cargo install sccache diff --git a/secure/storage/github/src/lib.rs b/secure/storage/github/src/lib.rs index 46b8c601c2..e3f9d659be 100644 --- a/secure/storage/github/src/lib.rs +++ b/secure/storage/github/src/lib.rs @@ -260,6 +260,24 @@ impl Client { } } + ///////// 0L //////// + pub fn delete_own_repo(&self, forked_repo_owner: &str, forked_repo_name: &str) -> Result<(), Error> { + let json = json!({}); + + let api_path = format!("https://api.github.com/repos/{}/{}", forked_repo_owner, forked_repo_name); + let resp = self + .upgrade_request(ureq::delete(&api_path)) + .send_json(json); + + match resp.status() { + 200 => Ok(()), + 201 => Ok(()), + 202 => Ok(()), + _ => Err(resp.into()), + } + } + + ///////// 0L ////////