Homestead_21 – Ethereum Tests

Documentos Visualizados » Colabora Traduciendo » Homestead_21 – Ethereum Tests

Ethereum Tests

Common tests for all clients to test against. The git repo updated regulary with new tests.
This section describes basic test concepts and templates which are created by cpp-client.

Using Testeth

Ethereum cpp-client testeth tool for creation and execution of ethereum tests.

To run tests you should open folder (see also Installing and building)

/build/libethereum/test

and execute a command ./testeth This will run all test cases automatically. To run a specific test case you could use parameter -t in the command line option:

./testeth -t <TEST_SUITE>/<TEST_CASE>

Or just the test suite:

./testeth -t <TEST_SUITE>

You could also use --filltests option to rerun test creation from .json files which are located at ../cpp-ethereum/test/<TEST_FILLER>.json

./testeth -t <TEST_SUITE>/<TEST_CASE> --filltests

By default using --filltests option testeth recreate tests to the ETHEREUM_TEST_PATH folder. You might want to set this variable globally on your system like:

nano /etc/environment
ETHEREUM_TEST_PATH="/home/user/ethereum/tests"

Filler files are test templates which are used to fill initial parameters defined at test specification Ethereum Tests and then create a complete test .json file. You might find filler files very useful when creating your own tests.

The --checkstate option adds a BOOST error if the post state of filled test differs from its expectedsection.

To specify a concrete test in a TEST_CASE file for filling/running procedure use --singletest option:

./testeth -t <TEST_SUITE>/<TEST_CASE> --singletest <TEST_NAME>

If you want to debug (note: testeth should be build with VMTRACE=1) a single test within a result test .json file, you might use the following command:

./testeth --log_level=test_suite --run_test=<TEST_SUITE>/<TEST_CASE> --singletest <TEST_FILE>.json
<TEST_NAME> --vmtrace --verbosity 12
or
./testeth -t <TEST_SUITE>/<TEST_CASE> --singletest <TEST_NAME> --vmtrace --verbosity 12

Some tests may use excessive resources when running, so by default they are disabled. Such tests require specific flag to be set in order to be executed. Like --performance, --inputLimits, --memory, --quadratic. You may also enable all of the tests by setting --all flag. Be careful. Enabled memory tests may stress your system to use 4GB of RAM and more.

That’s it for test execution. To read more about command line options you may run testeth with --help option.

Now let’s see what test cases are available.

Test Cases

Almost each test case has its filler file available at /webthree-umbrella/libethereum/test

TEST_SUITE = BlockTests TEST_CASES = blValidBlockTest blInvalidTransactionRLP blTransactionTest blInvalidHeaderTest userDefinedFile

TEST_SUITE = TransactionTests TEST_CASES = ttTransactionTest ttWrongRLPTransaction tt10mbDataField userDefinedFile

TEST_SUITE = StateTests TEST_CASES = stExample stSystemOperationsTest stPreCompiledContracts stLogTests stRecursiveCreate stTransactionTest stInitCodeTest stSpecialTest stRefundTest stBlockHashTest stQuadraticComplexityTest stSolidityTest stMemoryTest stCreateTest userDefinedFileState

TEST_SUITE = VMTests TEST_CASES = vm_tests vmArithmeticTest vmBitwiseLogicOperationTest vmSha3Test vmEnvironmentalInfoTest vmBlockInfoTest vmIOandFlowOperationsTest vmPushDupSwapTest vmLogTest vmSystemOperationsTest vmPerformanceTest vmInputLimitsTest1 vmInputLimitsTest2 vmRandom userDefinedFile

Blockchain Tests

Found in /BlockTests, the blockchain tests aim is to test the basic verification of a blockchain.

/BlockTests – general blockchain tests. All blocks are built on network: Frontier/BlockTests/Homestead – homestead blockchain tests. All blocks are built on network: Homestead/BlockTests/TestNetwork – transition blockchain tests. All blocks before 5th are built on network: Frontier, then each block should correspond to Homestead rules.

It is based around the notion of executing a list of single blocks, described by the blocks portion of the test. The first block is the modified genesis block as described by the genesisBlockHeader portion of the test. A set of pre-existing accounts are detailed in the pre portion and form the world state of the genesis block.

It is generally expected that the test implementer will read genesisBlockHeader and pre and build the corresponding blockchain in the client. Then the new blocks, described by its RLP found in the rlpobject of the blocks (RLP of a complete block, not the block header only), is read. If the client concludes that the block is valid, it should execute the block and verify the parameters given in blockHeader (block header of the new block), transactions (transaction list) and uncleHeaders (list of uncle headers). If the client concludes that the block is invalid, it should verify that no blockHeader, transactions or uncleHeaders object is present in the test. The client is expected to iterate through the list of blocks and ignore invalid blocks.

Basic structure

{
   "ValidBlocks": {
           "genesisBlockHeader": { ... },
           "pre": { ... },
           "blocks" : [
                   {
                           "chainname" : "A",
                           "blocknumber" : "1",
                           "rlp": { ... },
                           "blockHeader": { ... },
                           "transactions": { ... },
                           "uncleHeaders": { ... }
                   },
                   {
                           "chainname" : "A",
                           "blocknumber" : "2",
                           "rlp": { ... },
                           "blockHeader": { ... },
                           "transactions": { ... },
                           "uncleHeaders": { ... }
                   }
           ]
   },
   "SomeInvalidBlocks": {
           "genesisBlockHeader": { ... },
           "pre": { ... },
           "blocks" : [
                   {
                           "chainname" : "B",
                           "blocknumber" : "3",
                           "chainnetwork" : "Frontier",
                           "rlp": { ... },
                   },
                   {
                           "blocknumber" : "1",
                           "rlp": { ... },
                           "blockHeader": { ... },
                           "transactions": { ... },
                           "uncleHeaders": { ... }
                   },
                   {
                           "blocknumber" : "1",
                           "chainnetwork" : "Homestead",
                           "rlp": { ... },
                   },
                   {
                           "blocknumber" : "2",
                           "rlp": { ... },
                           "blockHeader": { ... },
                           "transactions": { ... },
                           "uncleHeaders": { ... }
                   }
           ]
   },
   ...
}

Sections

  • The genesisBlockHeader section
coinbase:
The 160-bit address to which all fees collected from the successful mining of this block be transferred, as returned by the COINBASE instruction.
difficulty:
A scalar value corresponding to the difficulty level of this block. This can be alculated from the previous block’s difficulty level and the timestamp, as returned by the DIFFICULTY instruction.
gasLimit:
A scalar value equal to the current limit of gas expenditure per block, as returned by the GASLIMIT instruction.
number:
A scalar value equal to the number of ancestor blocks. The genesis block has a number of zero.
timestamp:
A scalar value equal to the reasonable output of Unix’s time() at this block’s inception, as returned by the TIMESTAMP instruction.
parentHash:
The Keccak 256-bit hash of the parent block’s header, in its entirety
bloom:
The Bloom filter composed from indexable information (logger address and log topics) contained in each log entry from the receipt of each transaction in the transactions list.
extraData:
An arbitrary byte array containing data relevant to this block. This must be 1024 bytes or fewer.
gasUsed:
A scalar value equal to the total gas used in transactions in this block.
nonce:
A 256-bit hash which proves that a sufficient amount of computation has been carried out on this block.
receiptTrie:
The Keccak 256-bit hash of the root node of the trie structure populated with the receipts of each transaction in the transactions list portion of the block.
stateRoot:
The Keccak 256-bit hash of the root node of the state trie, after all transactions are executed and finalisations applied.
transactionsTrie:
The Keccak 256-bit hash of the root node of the trie structure populated with each transaction in the transactions list portion of the block.
uncleHash:
The Keccak 256-bit hash of the uncles list portion of this block
  • pre section: as described in State Tests.
  • postState section: as described in State Tests (section – post).
  • blocks section is a list of block objects, which have the following format:
  • rlp section contains the complete rlp of the new block as described in the yellow paper in section 4.3.3.
  • blockHeader section describes the block header of the new block in the same format as described in genesisBlockHeader.
  • transactions section is a list of transactions which have the same format as in Transaction Tests.
  • uncleHeaders section is a list of block headers which have the same format as descibed in genesisBlockHeader.

Optional BlockHeader Sections (Information fields)

"blocknumber" = "int" is section which defines what is the order of this block. It is used to define a situation when you have 3 blocks already imported but then it comes new version of the block 2 and 3 and thus you might have new best blockchain with blocks 1 2’ 3’ instead previous. If blocknumber is undefined then it is assumed that blocks are imported one by one. When running test, this field could be used for information purpose only.

"chainname" = "string" This is used for defining forks in the same test. You could mine blocks to chain “A”: 1, 2, 3 then to chain “B”: 1, 2, 3, 4 (chainB becomes primary). Then again to chain “A”: 4, 5, 6 (chainA becomes primary) and so on. chainname could also be defined in uncle header section. If defined in uncle header it tells on which chain’s block uncle header would be populated from. When running test, this field could be used for information purpose only.

"chainnetwork" = "string" Defines on which network rules this block was mined. (see the difference https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki). When running test, this field could be used for information purpose only.

State Tests

Found in /StateTest, the state tests aim is to test the basic workings of the state in isolation.

It is based around the notion of executing a single transaction, described by the transaction portion of the test. The overarching environment in which it is executed is described by the env portion of the test and includes attributes of the current and previous blocks. A set of pre-existing accounts are detailed in the pre portion and form the world state prior to execution. Similarly, a set of accounts are detailed in the post portion to specify the end world state. Since the data of the blockchain is not given, the opcode BLOCKHASH could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n to be SHA256("n").

The log entries (logs) as well as any output returned from the code (output) is also detailed.

It is generally expected that the test implementer will read env, transaction and pre then check their results against logs, out, and post.

Basic structure

{
   "test name 1": {
           "env": { ... },
           "logs": { ... },
           "out": { ... },
           "post": { ... },
           "pre": { ... },
           "transaction": { ... },
   },
   "test name 2": {
           "env": { ... },
           "logs": { ... },
           "out": { ... },
           "post": { ... },
           "pre": { ... },
           "transaction": { ... },
   },
   ...
}

Sections

  • The env section:
currentCoinbase
The current block’s coinbase address, to be returned by the COINBASE instruction.
currentDifficulty
The current block’s difficulty, to be returned by the DIFFICULTY instruction.
currentGasLimit
The current block’s gas limit.
currentNumber
The current block’s number. Also indicates network rules for the transaction. Since blocknumber = 1000000 Homestead rules are applied to transaction. (see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki)
currentTimestamp
The current block’s timestamp.
previousHash
The previous block’s hash.
  • The transaction section:
data
The input data passed to the execution, as used by the CALLDATA… instructions. Given as an array of byte values. See $DATA_ARRAY.
gasLimit
The total amount of gas available for the execution, as would be returned by the GASinstruction were it be executed first.
gasPrice
The price of gas for the transaction, as used by the GASPRICE instruction.
nonce
Scalar value equal to the number of transactions sent by the sender.
address
The address of the account under which the code is executing, to be returned by the ADDRESS instruction.
secretKey
The secret key as can be derived by the v,r,s values if the transaction.
to
The address of the transaction’s recipient, to be returned by the ORIGIN instruction.
value
The value of the transaction (or the endowment of the create), to be returned by the CALLVALUE` instruction (if executed first, before any CALL).
  • The pre and post sections each have the same format of a mapping between addresses and accounts. Each account has the format:
balance
The balance of the account.
nonce
The nonce of the account.
code
The body code of the account, given as an array of byte values. See $DATA_ARRAY.
storage
The account’s storage, given as a mapping of keys to values. For key used notion of string as digital or hex number e.g: "1200" or "0x04B0" For values used $DATA_ARRAY.
The logs sections is a mapping between the blooms and their corresponding logentries.
Each logentry has the format:
address The address of the logentry.
data The data of the logentry.
topics The topics of the logentry, given as an array of values.

Finally, there is one simple key output

output
The data, given as an array of bytes, returned from the execution (using the RETURN instruction). See $DATA_ARRAY. In order to avoid big data files, there is one exception. If the output data is prefixed with #, the following number represents the size of the output, and not the output directly.
$DATA_ARRAY – type that intended to contain raw byte data

and for convenient of the users is populated with three types of numbers, all of them should be converted and concatenated to a byte array for VM execution.

The types are:

  1. number – (unsigned 64bit)
  2. “longnumber” – (any long number)
  3. “0xhex_num” – (hex format number)
e.g: ````[1, 2, 10000, "0xabc345dFF", "199999999999999999999999999999999999999"]````

RLP Tests

Describes an RLP (https://github.com/ethereum/wiki/wiki/RLP) encoding using the .json file. The client should read the rlp byte stream, decode and check whether the contents match its json representation. Then it should try do it reverse – encode json rlp representation into rlp byte stream and check whether it matches the given rlp byte stream.

If it is an invalid RLP byte stream in the test, then ‘in’ field would contain string ‘INVALID’

Some RLP byte streams are expected to be generated by fuzz test suite. For those examples ‘in’ field would contain string ‘VALID’ as it means that rlp should be easily decoded.

RLP tests are located in in /RLPTests

Note that RLP tests are testing a single RLP object encoding. Not a stream of RLP objects in one array.

Basic structure

{
   "rlpTest": {
        "in": "dog",
        "out": "83646f67"
   },

   "multilist": {
        "in": [ "zw", [ 4 ], 1 ],
        "out": "c6827a77c10401"
   },

   "validRLP": {
        "in": "VALID",
        "out": "c7c0c1c0c3c0c1c0"
   },

   "invalidRLP": {
        "in": "INVALID",
        "out": "bf0f000000000000021111"
   },
   ...
}

Sections

  • in – json object (array, int, string) representation of the rlp byte stream (*except values ‘VALID’ and ‘INVALID’)
  • out – string of rlp bytes stream

Difficulty Tests

Found in Basic Testsdifficulty*.json files. This tests are designed to just check the difficulty formula of a block.

difficulty = DIFFICULTY(currentBlockNumber, currentTimestamp, parentTimestamp, parentDifficulty)

described at [EIP2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki) point 4 with homestead changes.

So basically this .json tests are just to check how this function is calculated on different function parameters (parentDifficulty, currentNumber) in its extremum points.

There are several test files:

difficulty.json
Normal Frontier/Homestead chain difficulty tests defined manually
difficultyFrontier.json
Same as above, but auto-generated tests
difficultyMorden.json
Tests for testnetwork difficulty. (it has different homestead transition block)
difficultyOlimpic.json
Olympic network. (no homestead)
difficultyHomestead.json
Tests for homestead difficulty (regardless of the block number)
difficultyCustomHomestead.json
Tests for homestead difficulty (regardless of the block number)

Basic structure

{
        "difficultyTest" : {
                "parentTimestamp" : "42",
                "parentDifficulty" : "1000000",
                "currentTimestamp" : "43",
                "currentBlockNumber" : "42",
                "currentDifficulty" : "1000488"
        }
}

Sections

  • parentTimestamp – indicates the timestamp of a previous block
  • parentDifficulty – indicates the difficulty of a previous block
  • currentTimestamp – indicates the timestamp of a current block
  • currentBlockNumber – indicates the number of a current block (previous block number = currentBlockNumber – 1)
  • currentDifficulty – indicates the difficulty of a current block

Transaction Tests

Describes a complete transaction and its RLP representation using the .json file. The client should read the rlp and check whether the transaction is valid, has the correct sender and corresponds to the transaction parameters. If it is an invalid transaction, the transaction and the sender object will be missing.

Basic structure

{
   "transactionTest1": {
          "rlp" : "bytearray",
          "sender" : "address",
          "blocknumber" : "1000000"
          "transaction" : {
                        "nonce" : "int",
                        "gasPrice" : "int",
                        "gasLimit" : "int",
                        "to" : "address",
                        "value" : "int",
                        "v" : "byte",
                        "r" : "256 bit unsigned int",
                        "s" : "256 bit unsigned int",
                        "data" : "byte array"
          }
   },

   "invalidTransactionTest": {
          "rlp" : "bytearray",
   },
   ...
}

Sections

  • rlp – RLP encoded data of this transaction
  • transaction – transaction described by fields
  • nonce – A scalar value equal to the number of transactions sent by the sender.
  • gasPrice – A scalar value equal to the number of wei to be paid per unit of gas.
  • gasLimit – A scalar value equal to the maximum amount of gas that should be used in executing this transaction.
  • to – The 160-bit address of the message call’s recipient or empty for a contract creation transaction.
  • value – A scalar value equal to the number of wei to be transferred to the message call’s recipient or, in the case of contract creation, as an endowment to the newly created account.
  • v, r, s – Values corresponding to the signature of the transaction and used to determine the sender of the transaction.
  • sender – the address of the sender, derived from the v,r,s values.
  • blocknumber – indicates network rules for the transaction. Since blocknumber = 1000000Homestead rules are applied to transaction. (see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki)

VM Tests

Found in /VMTest, the VM tests aim is to test the basic workings of the VM in isolation. This is specifically not meant to cover transaction, creation or call processing, or management of the state trie. Indeed at least one implementation tests the VM without calling into any Trie code at all.

It is based around the notion of executing a single piece of code as part of a transaction, described by the exec portion of the test. The overarching environment in which it is executed is described by the env portion of the test and includes attributes of the current and previous blocks. A set of pre-existing accounts are detailed in the pre portion and form the world state prior to execution. Similarly, a set of accounts are detailed in the post portion to specify the end world state.

The gas remaining (gas), the log entries (logs) as well as any output returned from the code (output) is also detailed.

Because the data of the blockchain is not given, the opcode BLOCKHASH could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n to be SHA3-256(“n”).

Since these tests are meant only as a basic test of VM operation, the CALL and CREATE instructions are not actually executed. To provide the possibility of testing to guarantee they were actually run at all, a separate portion callcreates details each CALL or CREATE operation in the order they would have been executed. Furthermore, gas required is simply that of the VM execution: the gas cost for transaction processing is excluded.

It is generally expected that the test implementer will read env, exec and pre then check their results against gas, logs, out, post and callcreates. If an exception is expected, then latter sections are absent in the test. Since the reverting of the state is not part of the VM tests.

Basic structure

{
   "test name 1": {
           "env": { ... },
           "pre": { ... },
           "exec": { ... },
           "gas": { ... },
           "logs": { ... },
           "out": { ... },
           "post": { ... },
           "callcreates": { ... }
   },
   "test name 2": {
           "env": { ... },
           "pre": { ... },
           "exec": { ... },
           "gas": { ... },
           "logs": { ... },
           "out": { ... },
           "post": { ... },
           "callcreates": { ... }
   },
   ...
}

Sections

The env section:

  • currentCoinbase: The current block’s coinbase address, to be returned by the COINBASEinstruction.
  • currentDifficulty: The current block’s difficulty, to be returned by the DIFFICULTY instruction.
  • currentGasLimit: The current block’s gas limit.
  • currentNumber: The current block’s number.
  • currentTimestamp: The current block’s timestamp.
  • previousHash: The previous block’s hash.

The exec section:

  • address: The address of the account under which the code is executing, to be returned by the ADDRESS instruction.
  • origin: The address of the execution’s origin, to be returned by the ORIGIN instruction.
  • caller: The address of the execution’s caller, to be returned by the CALLER instruction.
  • value: The value of the call (or the endowment of the create), to be returned by the CALLVALUEinstruction.
  • data: The input data passed to the execution, as used by the CALLDATA… instructions. Given as an array of byte values. See $DATA_ARRAY.
  • code: The actual code that should be executed on the VM (not the one stored in the state(address)) . See $DATA_ARRAY.
  • gasPrice: The price of gas for the transaction, as used by the GASPRICE instruction.
  • gas: The total amount of gas available for the execution, as would be returned by the GASinstruction were it be executed first.

The pre and post sections each have the same format of a mapping between addresses and accounts. Each account has the format:

  • balance: The balance of the account.
  • nonce: The nonce of the account.
  • code: The body code of the account, given as an array of byte values. See $DATA_ARRAY.
  • storage: The account’s storage, given as a mapping of keys to values. For key used notion of string as digital or hex number e.g: "1200" or "0x04B0" For values used $DATA_ARRAY.

The callcreates section details each CALL or CREATE instruction that has been executed. It is an array of maps with keys:

  • data: An array of bytes specifying the data with which the CALL or CREATE operation was made. In the case of CREATE, this would be the (initialisation) code. See $DATA_ARRAY.
  • destination: The receipt address to which the CALL was made, or the null address ("0000...") if the corresponding operation was CREATE.
  • gasLimit: The amount of gas with which the operation was made.
  • value: The value or endowment with which the operation was made.

The logs sections is a mapping between the blooms and their corresponding logentries. Each logentry has the format:

  • address: The address of the logentry.
  • data: The data of the logentry.
  • topics: The topics of the logentry, given as an array of values.

Finally, there are two simple keys, gas and output:

  • gas: The amount of gas remaining after execution.
  • output: The data, given as an array of bytes, returned from the execution (using the RETURNinstruction). See $DATA_ARRAY.
$DATA_ARRAY – type that intended to contain raw byte data
and for convenient of the users is populated with three types of numbers, all of them should be converted and concatenated to a byte array for VM execution.
  • The types are: 1. number – (unsigned 64bit) 2. “longnumber” – (any long number) 3. “0xhex_num” – (hex format number)

    e.g: ````[1, 2, 10000, "0xabc345dFF", "199999999999999999999999999999999999999"]````

     

Web3 Base Layer Services

In addition to the Ethereum blockchain, more components are being developed that decentralise other important aspects of web applications.

../_images/ethereum-protocols.png

Swarm – Decentralised data storage and distribution

Swarm is a peer to peer data sharing network in which files are addressed by the hash of their content. Similar to Bittorrent, it is possible to fetch the data from many nodes at once and as long as a single node hosts a piece of data, it will remain accessible everywhere. This approach makes it possible to distribute data without having to host any kind of server – data accessibility is location independent.

Other nodes in the network can be incentivised to replicate and store the data themselves, obviating the need for hosting services when the original nodes are not connected to the network.

Whisper – Decentralised messaging

A protocol for private, secure communication directly between nodes.


Furthermore, standard contracts are being created to make the development and usage of distributed applications easier:

Name registry

Because dapps can be stored anywhere, including the Swarm network, the name registry maps names to their content or location. This is a decentralised alternative to the Domain Name System (DNS).

See https://github.com/ethereum/EIPs/issues/26

Contract registry

To publish the source code of a specific contract, its address has to be mapped to it. The contract registry stores this mapping. Users can then look up this mapping and verify the contract byte code.

See * global registrar code * namereg API

You must be logged in to take the quiz.

Deja un comentario