transition-test.sh 6.4 KB

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