vdev Knot.Block

Models the functionality of a block.

The Knot.Block module exposes function to interact with blocks.

Link to this section Summary

Types

Represents a mining difficulty level

Represents the height of a block within a chain

Represents a block identifier

Represents the adjustment to be made to a block for it to be mined

t()

Carries data representing a block

Represents a point in time

Functions

Retrieves a block’s ancestry

Checks whether a given block’s ancestry contains a block or not

Builds the genesis block using the application configuration data

Assigns a parent block to a given block, and sets the hashes and height accordingly

Builds a changeset for a block

Clears the store completely

Given a block’s height, computes its required difficulty

Verifies the validity of a single block by checking that:

  • parent_hash, content_hash, component_hash or hash are valid,
  • The content and component hash were properly sealed,
  • The block’s hash and nonce are a solution

Verifies all of a given block’s parents are well known

Verifies whether a given block was properly mined or not

Finds a block by its hash

Finds a block by its height and hash

Returns the genesis block. A genesis block should have its parent hash set to a 32 bytes zero’ed binary and have a height of 0

Makes a new block given a timestamp and a content hash

Removes a block from the store

Hashes the block components to prevent any further modification

Adds a block to the store

Link to this section Types

Link to this type difficulty()
difficulty() :: non_neg_integer

Represents a mining difficulty level.

Link to this type finder_error()
finder_error() :: :not_found | :badarg
Link to this type finder_result()
finder_result() :: {:ok, Knot.Block.t} | {:error, finder_error}
Link to this type height()
height() :: non_neg_integer

Represents the height of a block within a chain.

Represents a block identifier.

It could be either one of:

  • A String.t, allowing special aliases like "head" and "genesis".
  • A Knot.Hash.t.
Link to this type insert_error()
insert_error() :: :insert_error
Link to this type mismatch_error()
mismatch_error() :: :component_hash_mismatch | :hash_mismatch
Link to this type nonce()
nonce() :: non_neg_integer

Represents the adjustment to be made to a block for it to be mined.

Link to this type t()
t() :: %Knot.Block{__meta__: term, component_hash: term, content_hash: term, hash: term, height: term, nonce: term, parent_hash: term, timestamp: term}

Carries data representing a block.

The Knot.Block.t data structure carries the important pieces of informations about a single block entity, without its content. Instead it embeds a hash of its content, allowing the block’s content to be stored separately using an appropriate back-end based on the type of application you’re running.

The block’s height, timestamp, parent hash and content hash are user defined, while the component hash, the nonce and the hash should be computed by this module.

Link to this type timestamp()
timestamp() :: integer

Represents a point in time.

Link to this section Functions

Link to this function ancestry(block, n \\ -1, ancestors \\ [])
ancestry(Knot.Block.t, integer, [Knot.Block.t]) ::
  {:ok, [Knot.Block.t]} |
  {:error, atom}

Retrieves a block’s ancestry.

Link to this function ancestry_contains?(b, a)
ancestry_contains?(Knot.Block.t, Knot.Block.t | Knot.Hash.t) :: boolean

Checks whether a given block’s ancestry contains a block or not.

Link to this function application_genesis()
application_genesis() :: Knot.Block.t

Builds the genesis block using the application configuration data.

Example

iex> g = Knot.Block.application_genesis()
iex> [g.height, g.nonce, g.timestamp]
[0, 3_492_211, 14_90_926_154]
Link to this function as_child_of(block, map)

Assigns a parent block to a given block, and sets the hashes and height accordingly.

Builds a changeset for a block.

Link to this function clear()
clear() :: :ok

Clears the store completely.

Link to this function count()
count() :: integer

Given a block’s height, computes its required difficulty.

Link to this function ensure_final(block)
ensure_final(Knot.Block.t) :: boolean | {:error, mismatch_error}

Verifies the validity of a single block by checking that:

  • parent_hash, content_hash, component_hash or hash are valid,
  • The content and component hash were properly sealed,
  • The block’s hash and nonce are a solution.
Link to this function ensure_known_parent(map)
ensure_known_parent(Knot.Block.t) :: :ok

Verifies all of a given block’s parents are well known.

Link to this function ensure_mined(block)
ensure_mined(Knot.Block.t) :: :ok | {:error, :unmined_block}

Verifies whether a given block was properly mined or not.

The checks ensure that:

  • The block’s ancestry is well known,
  • The block is final.

Finds a block by its hash.

Link to this function find_by_hash_and_height(hash, height)
find_by_hash_and_height(Knot.Hash.t, Knot.Block.height) :: finder_result

Finds a block by its height and hash.

Link to this function from_map(map)
from_map(map) :: Knot.Block.t

Returns the genesis block. A genesis block should have its parent hash set to a 32 bytes zero’ed binary and have a height of 0.

Example

iex> g = Knot.Block.from_map Application.get_env(:knot, :genesis_data)
iex> [g.height, g.nonce, g.timestamp]
[0, 3_492_211, 14_90_926_154]

Makes a new block given a timestamp and a content hash.

Examples

iex> Knot.Block.new <<1>>, 382_921_200
%Knot.Block{content_hash: <<1>>, timestamp: 382_921_200}
Link to this function remove(block)
remove(Knot.Block.t) :: :ok

Removes a block from the store.

Hashes the block components to prevent any further modification.

Once a block is sealed, it can safelly be mined. Sealing a block that was already sealed is acceptable, and often performed to verify whether the new seal matches the previous one, ensuring that the previous seal was correct.

Examples

iex> %Knot.Block{}
iex>   |> Knot.Block.seal
iex>   |> Map.get(:component_hash)
iex>   |> Knot.Hash.to_string(short: true)
"e3f001a9"
Link to this function store(block)
store(Knot.Block.t) ::
  {:ok, Knot.Block.t} |
  {:error, insert_error}

Adds a block to the store.