github.com/theQRL/go-zond@v0.2.1/cmd/zvm/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  function code(){
    24    echo "$ticks$1"
    25  }
    26  
    27  cat << "EOF"
    28  # ZVM tool
    29  
    30  The ZVM tool provides a few useful subcommands to facilitate testing at the ZVM
    31  layer.
    32  
    33  * transition tool    (`t8n`) : a stateless state transition utility
    34  * transaction tool   (`t9n`) : a transaction validation utility
    35  * block builder tool (`b11r`): a block assembler utility
    36  
    37  ## State transition tool (`t8n`)
    38  
    39  
    40  The `zvm t8n` tool is a stateless state transition utility. It is a utility
    41  which can
    42  
    43  1. Take a prestate, including
    44    - Accounts,
    45    - Block context information,
    46    - Previous blockshashes (*optional)
    47  2. Apply a set of transactions,
    48  3. Apply a mining-reward (*optional),
    49  4. And generate a post-state, including
    50    - State root, transaction root, receipt root,
    51    - Information about rejected transactions,
    52    - Optionally: a full or partial post-state dump
    53  
    54  ### Specification
    55  
    56  The idea is to specify the behaviour of this binary very _strict_, so that other
    57  node implementors can build replicas based on their own state-machines, and the
    58  state generators can swap between a \`gzond\`-based implementation and a \`parityvm\`-based
    59  implementation.
    60  
    61  #### Command line params
    62  
    63  Command line params that need to be supported are
    64  
    65  ```
    66  EOF
    67  ./zvm t8n -h | grep "\-\-trace\.\|\-\-output\.\|\-\-state\.\|\-\-input"
    68  cat << "EOF"
    69  ```
    70  #### Objects
    71  
    72  The transition tool uses JSON objects to read and write data related to the transition operation. The
    73  following object definitions are required.
    74  
    75  ##### `alloc`
    76  
    77  The `alloc` object defines the prestate that transition will begin with.
    78  
    79  ```go
    80  // Map of address to account definition.
    81  type Alloc map[common.Address]Account
    82  // Genesis account. Each field is optional.
    83  type Account struct {
    84      Code       []byte                           `json:"code"`
    85      Storage    map[common.Hash]common.Hash      `json:"storage"`
    86      Balance    *big.Int                         `json:"balance"`
    87      Nonce      uint64                           `json:"nonce"`
    88      Seed       []byte                           `json:"seed"`
    89  }
    90  ```
    91  
    92  ##### `env`
    93  
    94  The `env` object defines the environmental context in which the transition will
    95  take place.
    96  
    97  ```go
    98  type Env struct {
    99      // required
   100      CurrentCoinbase  common.Address      `json:"currentCoinbase"`
   101      CurrentGasLimit  uint64              `json:"currentGasLimit"`
   102      CurrentNumber    uint64              `json:"currentNumber"`
   103      CurrentTimestamp uint64              `json:"currentTimestamp"`
   104      Withdrawals      []*Withdrawal       `json:"withdrawals"`
   105      // optional
   106      CurrentRandom     *big.Int           `json:"currentRandom"`
   107      CurrentBaseFee    *big.Int           `json:"currentBaseFee"`
   108      ParentGasUsed     uint64             `json:"parentGasUsed"`
   109      ParentGasLimit    uint64             `json:"parentGasLimit"`
   110      ParentTimestamp   uint64             `json:"parentTimestamp"`
   111      BlockHashes       map[uint64]common.Hash `json:"blockHashes"`
   112  }
   113  type Withdrawal struct {
   114      Index          uint64         `json:"index"`
   115      ValidatorIndex uint64         `json:"validatorIndex"`
   116      Recipient      common.Address `json:"recipient"`
   117      Amount         *big.Int       `json:"amount"`
   118  }
   119  ```
   120  
   121  ##### `txs`
   122  
   123  The `txs` object is an array of any of the transaction types: `DynamicFeeTx`.
   124  
   125  ```go
   126  type AccessList []AccessTuple
   127  type AccessTuple struct {
   128  	Address     common.Address `json:"address"        gencodec:"required"`
   129  	StorageKeys []common.Hash  `json:"storageKeys"    gencodec:"required"`
   130  }
   131  type DynamicFeeTx struct {
   132  	ChainID    *big.Int        `json:"chainId"`
   133  	Nonce      uint64          `json:"nonce"`
   134  	GasTipCap  *big.Int        `json:"maxPriorityFeePerGas"`
   135  	GasFeeCap  *big.Int        `json:"maxFeePerGas"`
   136  	Gas        uint64          `json:"gas"`
   137  	To         *common.Address `json:"to"`
   138  	Value      *big.Int        `json:"value"`
   139  	Data       []byte          `json:"data"`
   140  	AccessList AccessList      `json:"accessList"`
   141  	PublicKey  []byte          `json:"publicKey"`
   142  	Signature  []byte          `json:"signature"`
   143    Seed       *common.Hash    `json:"seed"`
   144  }
   145  ```
   146  
   147  ##### `result`
   148  
   149  The `result` object is output after a transition is executed. It includes
   150  information about the post-transition environment.
   151  
   152  ```go
   153  type ExecutionResult struct {
   154      StateRoot   common.Hash    `json:"stateRoot"`
   155      TxRoot      common.Hash    `json:"txRoot"`
   156      ReceiptRoot common.Hash    `json:"receiptsRoot"`
   157      LogsHash    common.Hash    `json:"logsHash"`
   158      Bloom       types.Bloom    `json:"logsBloom"`
   159      Receipts    types.Receipts `json:"receipts"`
   160      Rejected    []*rejectedTx  `json:"rejected,omitempty"`
   161      GasUsed     uint64         `json:"gasUsed"`
   162      BaseFee     *big.Int       `json:"currentBaseFee,omitempty"`
   163  }
   164  ```
   165  
   166  #### Error codes and output
   167  
   168  All logging should happen against the `stderr`.
   169  There are a few (not many) errors that can occur, those are defined below.
   170  
   171  ##### ZVM-based errors (`2` to `9`)
   172  
   173  - Other ZVM error. Exit code `2`
   174  - Failed configuration: when a non-supported or invalid fork was specified. Exit code `3`.
   175  - Block history is not supplied, but needed for a `BLOCKHASH` operation. If `BLOCKHASH`
   176    is invoked targeting a block which history has not been provided for, the program will
   177    exit with code `4`.
   178  
   179  ##### IO errors (`10`-`20`)
   180  
   181  - Invalid input json: the supplied data could not be marshalled.
   182    The program will exit with code `10`
   183  - IO problems: failure to load or save files, the program will exit with code `11`
   184  
   185  ```
   186  # This should exit with 3
   187  ./zvm 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
   188  EOF
   189  ./zvm 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
   190  exitcode=$?
   191  if [ $exitcode !=  3 ]; then
   192  	echo "Failed, exitcode should be 3,was $exitcode"
   193  else
   194    echo "exitcode:$exitcode OK"
   195  fi
   196  cat << "EOF"
   197  ```
   198  #### Forks
   199  ### Basic usage
   200  
   201  The chain configuration to be used for a transition is specified via the
   202  `--state.fork` CLI flag. A list of possible values and configurations can be
   203  found in [`tests/init.go`](tests/init.go).
   204  
   205  #### Examples
   206  ##### Basic usage
   207  
   208  Invoking it with the provided example files
   209  EOF
   210  cmd="./zvm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Berlin"
   211  tick;echo "$cmd"; tick
   212  $cmd 2>/dev/null
   213  echo "Two resulting files:"
   214  echo ""
   215  showjson alloc.json
   216  showjson result.json
   217  echo ""
   218  
   219  echo "We can make them spit out the data to e.g. \`stdout\` like this:"
   220  cmd="./zvm 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 --state.fork=Berlin"
   221  tick;echo "$cmd"; tick
   222  output=`$cmd 2>/dev/null`
   223  echo "Output:"
   224  echo "${ticks}json"
   225  echo "$output"
   226  echo "$ticks"
   227  
   228  echo "#### Future EIPS"
   229  echo ""
   230  echo "It is also possible to experiment with future eips that are not yet defined in a hard fork."
   231  echo "Example, putting EIP-1344 into Frontier: "
   232  cmd="./zvm t8n --state.fork=Frontier+1344 --input.pre=./testdata/1/pre.json --input.txs=./testdata/1/txs.json --input.env=/testdata/1/env.json"
   233  tick;echo "$cmd"; tick
   234  echo ""
   235  
   236  echo "#### Block history"
   237  echo ""
   238  echo "The \`BLOCKHASH\` opcode requires blockhashes to be provided by the caller, inside the \`env\`."
   239  echo "If a required blockhash is not provided, the exit code should be \`4\`:"
   240  echo "Example where blockhashes are provided: "
   241  demo "./zvm t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace --state.fork=Shanghai"
   242  cmd="cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2"
   243  tick && echo $cmd && tick
   244  echo "$ticks"
   245  cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2
   246  echo "$ticks"
   247  echo ""
   248  
   249  echo "In this example, the caller has not provided the required blockhash:"
   250  cmd="./zvm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json  --trace --state.fork=Shanghai"
   251  tick && echo $cmd && $cmd 2>&1
   252  errc=$?
   253  tick
   254  echo "Error code: $errc"
   255  echo ""
   256  
   257  echo "#### Chaining"
   258  echo ""
   259  echo "Another thing that can be done, is to chain invocations:"
   260  cmd1="./zvm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Shanghai --output.alloc=stdout"
   261  cmd2="./zvm t8n --input.alloc=stdin --input.env=./testdata/1/env.json --input.txs=./testdata/1/txs.json --state.fork=Shanghai"
   262  echo "$ticks"
   263  echo "$cmd1 | $cmd2"
   264  output=$($cmd1 | $cmd2 )
   265  echo $output
   266  echo "$ticks"
   267  echo "What happened here, is that we first applied two identical transactions, so the second one was rejected. "
   268  echo "Then, taking the poststate alloc as the input for the next state, we tried again to include"
   269  echo "the same two transactions: this time, both failed due to too low nonce."
   270  echo ""
   271  echo "In order to meaningfully chain invocations, one would need to provide meaningful new \`env\`, otherwise the"
   272  echo "actual blocknumber (exposed to the ZVM) would not increase."
   273  echo ""
   274  
   275  echo "#### Transactions in RLP form"
   276  echo ""
   277  echo "It is possible to provide already-signed transactions as input to, using an \`input.txs\` which ends with the \`rlp\` suffix."
   278  echo "The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible"
   279  echo "to use the zvm to go from \`json\` input to \`rlp\` input."
   280  echo ""
   281  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\`.:"
   282  cmd="./zvm t8n --state.fork=Shanghai --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"
   283  echo "$ticks"
   284  echo $cmd
   285  $cmd 2>&1
   286  echo "$ticks"
   287  echo ""
   288  echo "The \`output.body\` is the rlp-list of transactions, encoded in hex and placed in a string a'la \`json\` encoding rules:"
   289  demo "cat signed_txs.rlp"
   290  echo "We can use \`rlpdump\` to check what the contents are: "
   291  echo "$ticks"
   292  echo "rlpdump -hex \$(cat signed_txs.rlp | jq -r )"
   293  rlpdump -hex $(cat signed_txs.rlp | jq -r )
   294  echo "$ticks"
   295  echo "Now, we can now use those (or any other already signed transactions), as input, like so: "
   296  cmd="./zvm t8n --state.fork=Shanghai --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json"
   297  echo "$ticks"
   298  echo $cmd
   299  $cmd 2>&1
   300  echo "$ticks"
   301  echo "You might have noticed that the results from these two invocations were stored in two separate files. "
   302  echo "And we can now finally check that they match."
   303  echo "$ticks"
   304  echo "cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot"
   305  cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
   306  echo "$ticks"
   307  
   308  cat << "EOF"
   309  
   310  ## Transaction tool
   311  
   312  The transaction tool is used to perform static validity checks on transactions such as:
   313  * intrinsic gas calculation
   314  * max values on integers
   315  * fee semantics, such as `maxFeePerGas < maxPriorityFeePerGas`
   316  * newer tx types on old forks
   317  
   318  ### Examples
   319  
   320  EOF
   321  
   322  cmd="./zvm t9n --state.fork Shanghai --input.txs testdata/15/signed_txs.rlp"
   323  tick;echo "$cmd";
   324  $cmd 2>/dev/null
   325  tick
   326  
   327  cat << "EOF"
   328  ## Block builder tool (b11r)
   329  
   330  The `zvm b11r` tool is used to assemble and seal full block rlps.
   331  
   332  ### Specification
   333  
   334  #### Command line params
   335  
   336  Command line params that need to be supported are:
   337  
   338  ```
   339      --input.header value        `stdin` or file name of where to find the block header to use. (default: "header.json")
   340      --input.txs value           `stdin` or file name of where to find the transactions list in RLP form. (default: "txs.rlp")
   341      --output.basedir value      Specifies where output files are placed. Will be created if it does not exist.
   342      --output.block value        Determines where to put the alloc of the post-state. (default: "block.json")
   343                                  <file> - into the file <file>
   344                                  `stdout` - into the stdout output
   345                                  `stderr` - into the stderr output
   346      --verbosity value           Sets the verbosity level. (default: 3)
   347  ```
   348  
   349  #### Objects
   350  
   351  ##### `header`
   352  
   353  The `header` object is a consensus header.
   354  
   355  ```go=
   356  type Header struct {
   357          ParentHash  common.Hash       `json:"parentHash"`
   358          Coinbase    *common.Address   `json:"miner"`
   359          Root        common.Hash       `json:"stateRoot"         gencodec:"required"`
   360          TxHash      *common.Hash      `json:"transactionsRoot"`
   361          ReceiptHash *common.Hash      `json:"receiptsRoot"`
   362          Bloom       types.Bloom       `json:"logsBloom"`
   363          Number      *big.Int          `json:"number"            gencodec:"required"`
   364          GasLimit    uint64            `json:"gasLimit"          gencodec:"required"`
   365          GasUsed     uint64            `json:"gasUsed"`
   366          Time        uint64            `json:"timestamp"         gencodec:"required"`
   367          Extra       []byte            `json:"extraData"`
   368          Random      common.Hash       `json:"prevRandao"`
   369          Nonce       *types.BlockNonce `json:"nonce"`
   370          BaseFee     *big.Int          `json:"baseFeePerGas"`
   371  }
   372  ```
   373  #### `txs`
   374  
   375  The `txs` object is a list of RLP-encoded transactions in hex representation.
   376  
   377  ```go=
   378  type Txs []string
   379  ```
   380  
   381  #### `output`
   382  
   383  The `output` object contains two values, the block RLP and the block hash.
   384  
   385  ```go=
   386  type BlockInfo struct {
   387      Rlp  []byte      `json:"rlp"`
   388      Hash common.Hash `json:"hash"`
   389  }
   390  ```
   391  
   392  ## A Note on Encoding
   393  
   394  The encoding of values for `zvm` utility attempts to be relatively flexible. It
   395  generally supports hex-encoded or decimal-encoded numeric values, and
   396  hex-encoded byte values (like `common.Address`, `common.Hash`, etc). When in
   397  doubt, the [`execution-apis`](https://github.com/ethereum/execution-apis) way
   398  of encoding should always be accepted.
   399  
   400  ## Testing
   401  
   402  There are many test cases in the [`cmd/zvm/testdata`](./testdata) directory.
   403  These fixtures are used to power the `t8n` tests in
   404  [`t8n_test.go`](./t8n_test.go). The best way to verify correctness of new `zvm`
   405  implementations is to execute these and verify the output and error codes match
   406  the expected values.
   407  
   408  EOF