Skip to content

Latest commit

 

History

History
334 lines (199 loc) · 10.9 KB

DiemBlock.md

File metadata and controls

334 lines (199 loc) · 10.9 KB

Module 0x1::DiemBlock

This module defines a struct storing the metadata of the block and new block events.

Resource BlockMetadata

resource struct BlockMetadata
Fields
height: u64
Height of the current block
new_block_events: Event::EventHandle<DiemBlock::NewBlockEvent>
Handle where events with the time of new blocks are emitted

Struct NewBlockEvent

Fields
round: u64
proposer: address
previous_block_votes: vector<address>
time_microseconds: u64
On-chain time during he block at the given height

Constants

The BlockMetadata resource is in an invalid state

const EBLOCK_METADATA: u64 = 0;

An invalid signer was provided. Expected the signer to be the VM or a Validator.

const EVM_OR_VALIDATOR: u64 = 1;

Function initialize_block_metadata

This can only be invoked by the Association address, and only a single time. Currently, it is invoked in the genesis transaction

public fun initialize_block_metadata(account: &signer)
Implementation
public fun initialize_block_metadata(account: &signer) {
    DiemTimestamp::assert_genesis();
    // Operational constraint, only callable by the Association address
    CoreAddresses::assert_diem_root(account);

    assert(!is_initialized(), Errors::already_published(EBLOCK_METADATA));
    move_to<BlockMetadata>(
        account,
        BlockMetadata {
            height: 0,
            new_block_events: Event::new_event_handle<Self::NewBlockEvent>(account),
        }
    );
}
Specification

Function is_initialized

Helper function to determine whether this module has been initialized.

fun is_initialized(): bool
Implementation

Function block_prologue

Set the metadata for the current block. The runtime always runs this before executing the transactions in a block.

fun block_prologue(vm: &signer, round: u64, timestamp: u64, previous_block_votes: vector<address>, proposer: address)
Implementation
fun block_prologue(
    vm: &signer,
    round: u64,
    timestamp: u64,
    previous_block_votes: vector<address>,
    proposer: address
) acquires BlockMetadata {
    DiemTimestamp::assert_operating();
    // Operational constraint: can only be invoked by the VM.
    CoreAddresses::assert_vm(vm);

    // Authorization
    assert(
        proposer == CoreAddresses::VM_RESERVED_ADDRESS() || DiemSystem::is_validator(proposer),
        Errors::requires_address(EVM_OR_VALIDATOR)
    );

    let block_metadata_ref = borrow_global_mut<BlockMetadata>(CoreAddresses::DIEM_ROOT_ADDRESS());
    DiemTimestamp::update_global_time(vm, proposer, timestamp);
    block_metadata_ref.height = block_metadata_ref.height + 1;
    Event::emit_event<NewBlockEvent>(
        &mut block_metadata_ref.new_block_events,
        NewBlockEvent {
            round,
            proposer,
            previous_block_votes,
            time_microseconds: timestamp,
        }
    );
}
Specification

The below counter overflow is assumed to be excluded from verification of callers.

aborts_if [assume] get_current_block_height() + 1 > MAX_U64 with EXECUTION_FAILURE;

Function get_current_block_height

Get the current block height

public fun get_current_block_height(): u64
Implementation

Module Specification

Initialization

This implies that BlockMetadata is published after initialization and stays published ever after

invariant [global] DiemTimestamp::is_operating() ==> is_initialized();