starcoin-framework

Module 0x1::Block

Block module provide metadata for generated blocks.

use 0x1::CoreAddresses;
use 0x1::Errors;
use 0x1::Event;
use 0x1::Timestamp;

Resource BlockMetadata

Block metadata struct.

struct BlockMetadata has key
Fields
number: u64
number of the current block
parent_hash: vector<u8>
Hash of the parent block.
author: address
Author of the current block.
uncles: u64
number of uncles.
new_block_events: Event::EventHandle<Block::NewBlockEvent>
Handle of events when new blocks are emitted

Struct NewBlockEvent

Events emitted when new block generated.

struct NewBlockEvent has drop, store
Fields
number: u64
author: address
timestamp: u64
uncles: u64

Constants

const EBLOCK_NUMBER_MISMATCH: u64 = 17;

Function initialize

This can only be invoked by the GENESIS_ACCOUNT at genesis

public fun initialize(account: &signer, parent_hash: vector<u8>)
Implementation
public fun initialize(account: &signer, parent_hash: vector<u8>) {
    Timestamp::assert_genesis();
    CoreAddresses::assert_genesis_address(account);

    move_to<BlockMetadata>(
        account,
        BlockMetadata {
            number: 0,
            parent_hash: parent_hash,
            author: CoreAddresses::GENESIS_ADDRESS(),
            uncles: 0,
            new_block_events: Event::new_event_handle<Self::NewBlockEvent>(account),
        });
}
Specification
aborts_if !Timestamp::is_genesis();
aborts_if Signer::address_of(account) != CoreAddresses::SPEC_GENESIS_ADDRESS();
aborts_if exists<BlockMetadata>(Signer::address_of(account));

Function get_current_block_number

Get the current block number

public fun get_current_block_number(): u64
Implementation
public fun get_current_block_number(): u64 acquires BlockMetadata {
  borrow_global<BlockMetadata>(CoreAddresses::GENESIS_ADDRESS()).number
}
Specification
aborts_if !exists<BlockMetadata>(CoreAddresses::SPEC_GENESIS_ADDRESS());

Function get_parent_hash

Get the hash of the parent block.

public fun get_parent_hash(): vector<u8>
Implementation
public fun get_parent_hash(): vector<u8> acquires BlockMetadata {
  *&borrow_global<BlockMetadata>(CoreAddresses::GENESIS_ADDRESS()).parent_hash
}
Specification
aborts_if !exists<BlockMetadata>(CoreAddresses::SPEC_GENESIS_ADDRESS());

Function get_current_author

Gets the address of the author of the current block

public fun get_current_author(): address
Implementation
public fun get_current_author(): address acquires BlockMetadata {
  borrow_global<BlockMetadata>(CoreAddresses::GENESIS_ADDRESS()).author
}
Specification
aborts_if !exists<BlockMetadata>(CoreAddresses::SPEC_GENESIS_ADDRESS());

Function process_block_metadata

Call at block prologue

public fun process_block_metadata(account: &signer, parent_hash: vector<u8>, author: address, timestamp: u64, uncles: u64, number: u64)
Implementation
public fun process_block_metadata(account: &signer, parent_hash: vector<u8>,author: address, timestamp: u64, uncles:u64, number:u64) acquires BlockMetadata{
    CoreAddresses::assert_genesis_address(account);

    let block_metadata_ref = borrow_global_mut<BlockMetadata>(CoreAddresses::GENESIS_ADDRESS());
    assert!(number == (block_metadata_ref.number + 1), Errors::invalid_argument(EBLOCK_NUMBER_MISMATCH));
    block_metadata_ref.number = number;
    block_metadata_ref.author= author;
    block_metadata_ref.parent_hash = parent_hash;
    block_metadata_ref.uncles = uncles;

    Event::emit_event<NewBlockEvent>(
      &mut block_metadata_ref.new_block_events,
      NewBlockEvent {
          number: number,
          author: author,
          timestamp: timestamp,
          uncles: uncles,
      }
    );
}
Specification
aborts_if Signer::address_of(account) != CoreAddresses::SPEC_GENESIS_ADDRESS();
aborts_if !exists<BlockMetadata>(CoreAddresses::SPEC_GENESIS_ADDRESS());
aborts_if number != global<BlockMetadata>(CoreAddresses::SPEC_GENESIS_ADDRESS()).number + 1;
schema AbortsIfBlockMetadataNotExist {
    aborts_if !exists<BlockMetadata>(CoreAddresses::GENESIS_ADDRESS());
}

Module Specification

pragma verify;
pragma aborts_if_is_strict = true;