Skip to content

Latest commit

 

History

History
556 lines (305 loc) · 23.2 KB

DiemTransactionPublishingOption.md

File metadata and controls

556 lines (305 loc) · 23.2 KB

Module 0x1::DiemTransactionPublishingOption

This module defines a struct storing the publishing policies for the VM.

Struct DiemTransactionPublishingOption

Defines and holds the publishing policies for the VM. There are three possible configurations:

  1. No module publishing, only allow-listed scripts are allowed.
  2. No module publishing, custom scripts are allowed.
  3. Both module publishing and custom scripts are allowed. We represent these as the following resource.
struct DiemTransactionPublishingOption has copy, drop, store
Fields
script_allow_list: vector<vector<u8>>
Only script hashes in the following list can be executed by the network. If the vector is empty, no limitation would be enforced.
module_publishing_allowed: bool
Anyone can publish new module if this flag is set to true.

Resource HaltAllTransactions

If published, halts transactions from all accounts except DiemRoot

struct HaltAllTransactions has key
Fields
dummy_field: bool

Constants

The script hash already exists in the allowlist

Attempting to publish/unpublish a HaltAllTransactions resource that does not exist.

const EHALT_ALL_TRANSACTIONS: u64 = 2;

The script hash has an invalid length

const EINVALID_SCRIPT_HASH: u64 = 0;

const SCRIPT_HASH_LENGTH: u64 = 32;

Function initialize

public fun initialize(dr_account: &signer, script_allow_list: vector<vector<u8>>, module_publishing_allowed: bool)
Implementation
public fun initialize(
    dr_account: &signer,
    script_allow_list: vector<vector<u8>>,
    module_publishing_allowed: bool,
) {
    DiemTimestamp::assert_genesis();
    Roles::assert_diem_root(dr_account);

    DiemConfig::publish_new_config(
        dr_account,
        DiemTransactionPublishingOption {
            script_allow_list, module_publishing_allowed
        }
    );
}
Specification

Must abort if the signer does not have the DiemRoot role [H11].

Function is_script_allowed

Check if sender can execute script with hash

public fun is_script_allowed(account: &signer, hash: &vector<u8>): bool
Implementation
public fun is_script_allowed(account: &signer, hash: &vector<u8>): bool {
    // DiemRoot can send any script
    if (Roles::has_diem_root_role(account)) return true;

    // No one except DiemRoot can send scripts when transactions are halted
    if (transactions_halted()) return false;

    // The adapter passes an empty hash for script functions. All script functions are allowed
    if (Vector::is_empty(hash)) return true;

    let publish_option = DiemConfig::get<DiemTransactionPublishingOption>();
    // allowlist empty = open publishing, anyone can send txes
    Vector::is_empty(&publish_option.script_allow_list)
        // fixed allowlist. check inclusion
        || Vector::contains(&publish_option.script_allow_list, hash)
}
Specification

Function is_module_allowed

Check if a sender can publish a module

public fun is_module_allowed(account: &signer): bool
Implementation
public fun is_module_allowed(account: &signer): bool {
    let publish_option = DiemConfig::get<DiemTransactionPublishingOption>();

    publish_option.module_publishing_allowed || Roles::has_diem_root_role(account)
}
Specification

Function set_open_script

Allow the execution of arbitrary script or not.

public fun set_open_script(dr_account: &signer)
Implementation
public fun set_open_script(dr_account: &signer) {
    Roles::assert_diem_root(dr_account);
    let publish_option = DiemConfig::get<DiemTransactionPublishingOption>();

    publish_option.script_allow_list = Vector::empty();
    DiemConfig::set<DiemTransactionPublishingOption>(dr_account, publish_option);
}
Specification

Must abort if the signer does not have the DiemRoot role [H11].

Function set_open_module

Allow module publishing from arbitrary sender or not.

public fun set_open_module(dr_account: &signer, open_module: bool)
Implementation
public fun set_open_module(dr_account: &signer, open_module: bool) {
    Roles::assert_diem_root(dr_account);

    let publish_option = DiemConfig::get<DiemTransactionPublishingOption>();

    publish_option.module_publishing_allowed = open_module;
    DiemConfig::set<DiemTransactionPublishingOption>(dr_account, publish_option);
}
Specification

Must abort if the signer does not have the DiemRoot role [H11].

Function halt_all_transactions

If called, transactions cannot be sent from any account except DiemRoot

public fun halt_all_transactions(dr_account: &signer)
Implementation
public fun halt_all_transactions(dr_account: &signer) {
    Roles::assert_diem_root(dr_account);
    assert(
        !exists<HaltAllTransactions>(Signer::address_of(dr_account)),
        Errors::already_published(EHALT_ALL_TRANSACTIONS),
    );
    move_to(dr_account, HaltAllTransactions {});
}

Function resume_transactions

If called, transactions can be sent from any account once again

public fun resume_transactions(dr_account: &signer)
Implementation
public fun resume_transactions(dr_account: &signer) acquires HaltAllTransactions {
    Roles::assert_diem_root(dr_account);
    let dr_address = Signer::address_of(dr_account);
    assert(
        exists<HaltAllTransactions>(dr_address),
        Errors::already_published(EHALT_ALL_TRANSACTIONS),
    );

    let HaltAllTransactions {} = move_from<HaltAllTransactions>(dr_address);
}

Function transactions_halted

Return true if all non-administrative transactions are currently halted

fun transactions_halted(): bool
Implementation

Module Specification

Initialization

Access Control

Only set_open_script, and set_open_module can modify the DiemTransactionPublishingOption config [H11]

apply DiemVersionRemainsSame to * except set_open_script, set_open_module;

Helper Functions

fun spec_is_script_allowed(account: signer, hash: vector<u8>): bool {
    let publish_option = DiemConfig::spec_get_config<DiemTransactionPublishingOption>();
    Roles::has_diem_root_role(account) || (!transactions_halted() && (
        Vector::is_empty(hash) ||
            (Vector::is_empty(publish_option.script_allow_list)
                || contains(publish_option.script_allow_list, hash))
    ))
}

fun spec_is_module_allowed(account: signer): bool {
    let publish_option = DiemConfig::spec_get_config<DiemTransactionPublishingOption>();
    publish_option.module_publishing_allowed || Roles::has_diem_root_role(account)
}