github.com/codysnider/go-ethereum@v1.10.18-0.20220420071915-14f4ae99222a/cmd/evm/transition-test.sh (about)

     1  #!/bin/bash
     2  ticks="\`\`\`"
     3  
     4  function showjson(){
     5    echo "\`$1\`:"
     6    echo "${ticks}json"
     7    cat $1
     8    echo ""
     9    echo "$ticks"
    10  }
    11  function demo(){
    12    echo "$ticks"
    13    echo "$1"
    14    $1
    15    echo ""
    16    echo "$ticks"
    17    echo ""
    18  }
    19  function tick(){
    20    echo "$ticks"
    21  }
    22  
    23  cat << EOF
    24  ## EVM state transition tool
    25  
    26  The \`evm t8n\` tool is a stateless state transition utility. It is a utility
    27  which can
    28  
    29  1. Take a prestate, including
    30    - Accounts,
    31    - Block context information,
    32    - Previous blockshashes (*optional)
    33  2. Apply a set of transactions,
    34  3. Apply a mining-reward (*optional),
    35  4. And generate a post-state, including
    36    - State root, transaction root, receipt root,
    37    - Information about rejected transactions,
    38    - Optionally: a full or partial post-state dump
    39  
    40  ## Specification
    41  
    42  The idea is to specify the behaviour of this binary very _strict_, so that other
    43  node implementors can build replicas based on their own state-machines, and the
    44  state generators can swap between a \`geth\`-based implementation and a \`parityvm\`-based
    45  implementation.
    46  
    47  ### Command line params
    48  
    49  Command line params that has to be supported are
    50  $(tick)
    51  
    52  ` ./evm t8n -h | grep "trace\|output\|state\."`
    53  
    54  $(tick)
    55  
    56  ### Error codes and output
    57  
    58  All logging should happen against the \`stderr\`.
    59  There are a few (not many) errors that can occur, those are defined below.
    60  
    61  #### EVM-based errors (\`2\` to \`9\`)
    62  
    63  - Other EVM error. Exit code \`2\`
    64  - Failed configuration: when a non-supported or invalid fork was specified. Exit code \`3\`.
    65  - Block history is not supplied, but needed for a \`BLOCKHASH\` operation. If \`BLOCKHASH\`
    66    is invoked targeting a block which history has not been provided for, the program will
    67    exit with code \`4\`.
    68  
    69  #### IO errors (\`10\`-\`20\`)
    70  
    71  - Invalid input json: the supplied data could not be marshalled.
    72    The program will exit with code \`10\`
    73  - IO problems: failure to load or save files, the program will exit with code \`11\`
    74  
    75  EOF
    76  
    77  # This should exit with 3
    78  ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Frontier+1346 2>/dev/null
    79  if [ $? !=  3 ]; then
    80  	echo "Failed, exitcode should be 3"
    81  fi
    82  cat << EOF
    83  ## Examples
    84  ### Basic usage
    85  
    86  Invoking it with the provided example files
    87  EOF
    88  cmd="./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json"
    89  tick;echo "$cmd"; tick
    90  $cmd 2>/dev/null
    91  echo "Two resulting files:"
    92  echo ""
    93  showjson alloc.json
    94  showjson result.json
    95  echo ""
    96  
    97  echo "We can make them spit out the data to e.g. \`stdout\` like this:"
    98  cmd="./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --output.result=stdout --output.alloc=stdout"
    99  tick;echo "$cmd"; tick
   100  output=`$cmd 2>/dev/null`
   101  echo "Output:"
   102  echo "${ticks}json"
   103  echo "$output"
   104  echo "$ticks"
   105  
   106  cat << EOF
   107  
   108  ## About Ommers
   109  
   110  Mining rewards and ommer rewards might need to be added. This is how those are applied:
   111  
   112  - \`block_reward\` is the block mining reward for the miner (\`0xaa\`), of a block at height \`N\`.
   113  - For each ommer (mined by \`0xbb\`), with blocknumber \`N-delta\`
   114     - (where \`delta\` is the difference between the current block and the ommer)
   115     - The account \`0xbb\` (ommer miner) is awarded \`(8-delta)/ 8 * block_reward\`
   116     - The account \`0xaa\` (block miner) is awarded \`block_reward / 32\`
   117  
   118  To make \`state_t8n\` apply these, the following inputs are required:
   119  
   120  - \`state.reward\`
   121    - For ethash, it is \`5000000000000000000\` \`wei\`,
   122    - If this is not defined, mining rewards are not applied,
   123    - A value of \`0\` is valid, and causes accounts to be 'touched'.
   124  - For each ommer, the tool needs to be given an \`address\` and a \`delta\`. This
   125    is done via the \`env\`.
   126  
   127  Note: the tool does not verify that e.g. the normal uncle rules apply,
   128  and allows e.g two uncles at the same height, or the uncle-distance. This means that
   129  the tool allows for negative uncle reward (distance > 8)
   130  
   131  Example:
   132  EOF
   133  
   134  showjson ./testdata/5/env.json
   135  
   136  echo "When applying this, using a reward of \`0x08\`"
   137  cmd="./evm t8n --input.alloc=./testdata/5/alloc.json -input.txs=./testdata/5/txs.json --input.env=./testdata/5/env.json  --output.alloc=stdout --state.reward=0x80"
   138  output=`$cmd 2>/dev/null`
   139  echo "Output:"
   140  echo "${ticks}json"
   141  echo "$output"
   142  echo "$ticks"
   143  
   144  echo "### Future EIPS"
   145  echo ""
   146  echo "It is also possible to experiment with future eips that are not yet defined in a hard fork."
   147  echo "Example, putting EIP-1344 into Frontier: "
   148  cmd="./evm t8n --state.fork=Frontier+1344 --input.pre=./testdata/1/pre.json --input.txs=./testdata/1/txs.json --input.env=/testdata/1/env.json"
   149  tick;echo "$cmd"; tick
   150  echo ""
   151  
   152  echo "### Block history"
   153  echo ""
   154  echo "The \`BLOCKHASH\` opcode requires blockhashes to be provided by the caller, inside the \`env\`."
   155  echo "If a required blockhash is not provided, the exit code should be \`4\`:"
   156  echo "Example where blockhashes are provided: "
   157  demo "./evm --verbosity=1 t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace"
   158  cmd="cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2"
   159  tick && echo $cmd && tick
   160  echo "$ticks"
   161  cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2
   162  echo "$ticks"
   163  echo ""
   164  
   165  echo "In this example, the caller has not provided the required blockhash:"
   166  cmd="./evm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json  --trace"
   167  tick && echo $cmd && $cmd
   168  errc=$?
   169  tick
   170  echo "Error code: $errc"
   171  echo ""
   172  
   173  echo "### Chaining"
   174  echo ""
   175  echo "Another thing that can be done, is to chain invocations:"
   176  cmd1="./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --output.alloc=stdout"
   177  cmd2="./evm t8n --input.alloc=stdin --input.env=./testdata/1/env.json --input.txs=./testdata/1/txs.json"
   178  echo "$ticks"
   179  echo "$cmd1 | $cmd2"
   180  output=$($cmd1 | $cmd2 )
   181  echo $output
   182  echo "$ticks"
   183  echo "What happened here, is that we first applied two identical transactions, so the second one was rejected. "
   184  echo "Then, taking the poststate alloc as the input for the next state, we tried again to include"
   185  echo "the same two transactions: this time, both failed due to too low nonce."
   186  echo ""
   187  echo "In order to meaningfully chain invocations, one would need to provide meaningful new \`env\`, otherwise the"
   188  echo "actual blocknumber (exposed to the EVM) would not increase."
   189  echo ""
   190  
   191  echo "### Transactions in RLP form"
   192  echo ""
   193  echo "It is possible to provide already-signed transactions as input to, using an \`input.txs\` which ends with the \`rlp\` suffix."
   194  echo "The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible"
   195  echo "to use the evm to go from \`json\` input to \`rlp\` input."
   196  echo ""
   197  echo "The following command takes **json** the transactions in \`./testdata/13/txs.json\` and signs them. After execution, they are output to \`signed_txs.rlp\`.:"
   198  demo "./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./testdata/13/txs.json --input.env=./testdata/13/env.json --output.result=alloc_jsontx.json --output.body=signed_txs.rlp"
   199  echo "The \`output.body\` is the rlp-list of transactions, encoded in hex and placed in a string a'la \`json\` encoding rules:"
   200  demo "cat signed_txs.rlp"
   201  echo "We can use \`rlpdump\` to check what the contents are: "
   202  echo "$ticks"
   203  echo "rlpdump -hex \$(cat signed_txs.rlp | jq -r )"
   204  rlpdump -hex $(cat signed_txs.rlp | jq -r )
   205  echo "$ticks"
   206  echo "Now, we can now use those (or any other already signed transactions), as input, like so: "
   207  demo "./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json"
   208  
   209  echo "You might have noticed that the results from these two invocations were stored in two separate files. "
   210  echo "And we can now finally check that they match."
   211  echo "$ticks"
   212  echo "cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot"
   213  cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
   214  echo "$ticks"