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"