evm v0.1.14 Block.Header
This structure codifies the header of a block in the blockchain.
Link to this section Summary
Functions
Returns the total available gas left for all transactions in this block. This is the total gas limit minus the gas used in transactions
Deserializes a block header from an RLP encodable structure. This effectively undoes the encoding defined in L_H Eq.(32) of the Yellow Paper
Calculates the difficulty of a new block header. This implements Eq.(39), Eq.(40), Eq.(41), Eq.(42), Eq.(43) and Eq.(44) of the Yellow Paper
Computes hash of a block header, which is simply the hash of the serialized block header
Returns the block that defines the start of Homestead
Returns true if a given block is at or after the Homestead block
Returns true if a given block is before the Homestead block
Function to determine if the gas limit set is valid. The miner gets to specify a gas limit, so long as it’s in range. This allows about a 0.1% change per block
Returns true if the block header is valid. This defines Eq.(50), Eq.(51), Eq.(52), Eq.(53), Eq.(54), Eq.(55), Eq.(56), Eq.(57) and Eq.(58) of the Yellow Paper, commonly referred to as V(H)
This functions encode a header into a value that can be RLP encoded. This is defined as L_H Eq.(32) in the Yellow Paper
Link to this section Types
t() :: %Block.Header{beneficiary: EVM.address, difficulty: integer | nil, extra_data: binary, gas_limit: EVM.val, gas_used: EVM.val, logs_bloom: binary, mix_hash: EVM.hash | nil, nonce: <<_::64>> | nil, number: integer | nil, ommers_hash: EVM.trie_root, parent_hash: EVM.hash, receipts_root: EVM.trie_root, state_root: EVM.trie_root, timestamp: EVM.timestamp | nil, transactions_root: EVM.trie_root}
Link to this section Functions
Returns the total available gas left for all transactions in this block. This is the total gas limit minus the gas used in transactions.
Examples
iex> Block.Header.available_gas(%Block.Header{gas_limit: 50_000, gas_used: 30_000})
20_000
Deserializes a block header from an RLP encodable structure. This effectively undoes the encoding defined in L_H Eq.(32) of the Yellow Paper.
Examples
iex> Block.Header.deserialize([<<1::256>>, <<2::256>>, <<3::160>>, <<4::256>>, <<5::256>>, <<6::256>>, <<>>, <<5>>, <<1>>, <<5>>, <<3>>, <<6>>, "Hi mom", <<7::256>>, <<8::64>>])
%Block.Header{parent_hash: <<1::256>>, ommers_hash: <<2::256>>, beneficiary: <<3::160>>, state_root: <<4::256>>, transactions_root: <<5::256>>, receipts_root: <<6::256>>, logs_bloom: <<>>, difficulty: 5, number: 1, gas_limit: 5, gas_used: 3, timestamp: 6, extra_data: "Hi mom", mix_hash: <<7::256>>, nonce: <<8::64>>}
Calculates the difficulty of a new block header. This implements Eq.(39), Eq.(40), Eq.(41), Eq.(42), Eq.(43) and Eq.(44) of the Yellow Paper.
Examples
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 0, timestamp: 55},
...> nil
...> )
131_072
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 1, timestamp: 1479642530},
...> %Block.Header{number: 0, timestamp: 0, difficulty: 1_048_576}
...> )
1_048_064
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 33, timestamp: 66},
...> %Block.Header{number: 32, timestamp: 55, difficulty: 300_000}
...> )
300_146
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 33, timestamp: 88},
...> %Block.Header{number: 32, timestamp: 55, difficulty: 300_000}
...> )
299_854
# TODO: Is this right? These numbers are quite a jump
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 3_000_001, timestamp: 66},
...> %Block.Header{number: 3_000_000, timestamp: 55, difficulty: 300_000}
...> )
268_735_456
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 3_000_001, timestamp: 155},
...> %Block.Header{number: 3_000_000, timestamp: 55, difficulty: 300_000}
...> )
268_734_142
Test actual Ropsten genesis block
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 0, timestamp: 0},
...> nil,
...> 0x100000,
...> 0x020000,
...> 0x0800,
...> 0
...> )
1_048_576
# Test actual Ropsten first block
iex> Block.Header.get_difficulty(
...> %Block.Header{number: 1, timestamp: 1_479_642_530},
...> %Block.Header{number: 0, timestamp: 0, difficulty: 1_048_576},
...> 0x100000,
...> 0x020000,
...> 0x0800,
...> 0
...> )
997_888
Computes hash of a block header, which is simply the hash of the serialized block header.
This is defined in Eq.(37) of the Yellow Paper.
Examples
iex> %Block.Header{number: 5, parent_hash: <<1, 2, 3>>, beneficiary: <<2, 3, 4>>, difficulty: 100, timestamp: 11, mix_hash: <<1>>, nonce: <<2>>}
...> |> Block.Header.hash()
<<78, 28, 127, 10, 192, 253, 127, 239, 254, 179, 39, 34, 245, 44, 152, 98, 128, 71, 238, 155, 100, 161, 199, 71, 243, 223, 172, 191, 74, 99, 128, 63>>
iex> %Block.Header{number: 0, parent_hash: <<1, 2, 3>>, beneficiary: <<2, 3, 4>>, difficulty: 100, timestamp: 11, mix_hash: <<1>>, nonce: <<2>>}
...> |> Block.Header.hash()
<<218, 225, 46, 241, 196, 160, 136, 96, 109, 216, 73, 167, 92, 174, 91, 228, 85, 112, 234, 129, 99, 200, 158, 61, 223, 166, 165, 132, 187, 24, 142, 193>>
Returns the block that defines the start of Homestead.
This should be a constant, but it’s configurable on different chains, and as such, as allow you to pass that configuration variable (which ends up making this the identity function, if so).
is_after_homestead?(t, integer) :: boolean
Returns true if a given block is at or after the Homestead block.
Examples
iex> Block.Header.is_after_homestead?(%Block.Header{number: 5})
false
iex> Block.Header.is_after_homestead?(%Block.Header{number: 5_000_000})
true
iex> Block.Header.is_after_homestead?(%Block.Header{number: 1_150_000})
true
iex> Block.Header.is_after_homestead?(%Block.Header{number: 5}, 6)
false
is_before_homestead?(t, integer) :: boolean
Returns true if a given block is before the Homestead block.
Examples
iex> Block.Header.is_before_homestead?(%Block.Header{number: 5})
true
iex> Block.Header.is_before_homestead?(%Block.Header{number: 5_000_000})
false
iex> Block.Header.is_before_homestead?(%Block.Header{number: 1_150_000})
false
iex> Block.Header.is_before_homestead?(%Block.Header{number: 5}, 6)
true
iex> Block.Header.is_before_homestead?(%Block.Header{number: 5}, 4)
false
Function to determine if the gas limit set is valid. The miner gets to specify a gas limit, so long as it’s in range. This allows about a 0.1% change per block.
This function directly implements Eq.(45), Eq.(46) and Eq.(47).
Examples
iex> Block.Header.is_gas_limit_valid?(1_000_000, nil)
true
iex> Block.Header.is_gas_limit_valid?(1_000, nil)
false
iex> Block.Header.is_gas_limit_valid?(1_000_000, 1_000_000)
true
iex> Block.Header.is_gas_limit_valid?(1_000_000, 2_000_000)
false
iex> Block.Header.is_gas_limit_valid?(1_000_000, 500_000)
false
iex> Block.Header.is_gas_limit_valid?(1_000_000, 999_500)
true
iex> Block.Header.is_gas_limit_valid?(1_000_000, 999_000)
false
iex> Block.Header.is_gas_limit_valid?(1_000_000, 2_000_000, 1)
true
iex> Block.Header.is_gas_limit_valid?(1_000, nil, 1024, 500)
true
Returns true if the block header is valid. This defines Eq.(50), Eq.(51), Eq.(52), Eq.(53), Eq.(54), Eq.(55), Eq.(56), Eq.(57) and Eq.(58) of the Yellow Paper, commonly referred to as V(H).
TODO: Add proof of work check
Examples
iex> Block.Header.is_valid?(%Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000}, nil)
:valid
iex> Block.Header.is_valid?(%Block.Header{number: 0, difficulty: 5, gas_limit: 5}, nil, true)
{:invalid, [:invalid_difficulty, :invalid_gas_limit]}
iex> Block.Header.is_valid?(%Block.Header{number: 1, difficulty: 131_136, gas_limit: 200_000, timestamp: 65}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55})
:valid
iex> Block.Header.is_valid?(%Block.Header{number: 1, difficulty: 131_000, gas_limit: 200_000, timestamp: 65}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55}, true)
{:invalid, [:invalid_difficulty]}
iex> Block.Header.is_valid?(%Block.Header{number: 1, difficulty: 131_136, gas_limit: 200_000, timestamp: 45}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55})
{:invalid, [:child_timestamp_invalid]}
iex> Block.Header.is_valid?(%Block.Header{number: 1, difficulty: 131_136, gas_limit: 300_000, timestamp: 65}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55})
{:invalid, [:invalid_gas_limit]}
iex> Block.Header.is_valid?(%Block.Header{number: 2, difficulty: 131_136, gas_limit: 200_000, timestamp: 65}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55})
{:invalid, [:child_number_invalid]}
iex> Block.Header.is_valid?(%Block.Header{number: 1, difficulty: 131_136, gas_limit: 200_000, timestamp: 65, extra_data: "0123456789012345678901234567890123456789"}, %Block.Header{number: 0, difficulty: 131_072, gas_limit: 200_000, timestamp: 55})
{:invalid, [:extra_data_too_large]}
# TODO: Add tests for setting homestead_block
# TODO: Add tests for setting initial_difficulty
# TODO: Add tests for setting minimum_difficulty
# TODO: Add tests for setting difficulty_bound_divisor
# TODO: Add tests for setting gas_limit_bound_divisor
# TODO: Add tests for setting min_gas_limit
This functions encode a header into a value that can be RLP encoded. This is defined as L_H Eq.(32) in the Yellow Paper.
Examples
iex> Block.Header.serialize(%Block.Header{parent_hash: <<1::256>>, ommers_hash: <<2::256>>, beneficiary: <<3::160>>, state_root: <<4::256>>, transactions_root: <<5::256>>, receipts_root: <<6::256>>, logs_bloom: <<>>, difficulty: 5, number: 1, gas_limit: 5, gas_used: 3, timestamp: 6, extra_data: "Hi mom", mix_hash: <<7::256>>, nonce: <<8::64>>})
[<<1::256>>, <<2::256>>, <<3::160>>, <<4::256>>, <<5::256>>, <<6::256>>, <<>>, 5, 1, 5, 3, 6, "Hi mom", <<7::256>>, <<8::64>>]