github.com/theQRL/go-zond@v0.2.1/cmd/zvm/internal/t8ntool/block.go (about)

     1  // Copyright 2021 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package t8ntool
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"math/big"
    23  	"os"
    24  
    25  	"github.com/theQRL/go-zond/common"
    26  	"github.com/theQRL/go-zond/common/hexutil"
    27  	"github.com/theQRL/go-zond/common/math"
    28  	"github.com/theQRL/go-zond/core/types"
    29  	"github.com/theQRL/go-zond/log"
    30  	"github.com/theQRL/go-zond/rlp"
    31  	"github.com/urfave/cli/v2"
    32  )
    33  
    34  //go:generate go run github.com/fjl/gencodec -type header -field-override headerMarshaling -out gen_header.go
    35  type header struct {
    36  	ParentHash      common.Hash     `json:"parentHash"`
    37  	Coinbase        *common.Address `json:"miner"`
    38  	Root            common.Hash     `json:"stateRoot"        gencodec:"required"`
    39  	TxHash          *common.Hash    `json:"transactionsRoot"`
    40  	ReceiptHash     *common.Hash    `json:"receiptsRoot"`
    41  	Bloom           types.Bloom     `json:"logsBloom"`
    42  	Number          *big.Int        `json:"number"           gencodec:"required"`
    43  	GasLimit        uint64          `json:"gasLimit"         gencodec:"required"`
    44  	GasUsed         uint64          `json:"gasUsed"`
    45  	Time            uint64          `json:"timestamp"        gencodec:"required"`
    46  	Extra           []byte          `json:"extraData"`
    47  	Random          common.Hash     `json:"prevRandao"`
    48  	BaseFee         *big.Int        `json:"baseFeePerGas" rlp:"optional"`
    49  	WithdrawalsHash *common.Hash    `json:"withdrawalsRoot" rlp:"optional"`
    50  }
    51  
    52  type headerMarshaling struct {
    53  	Number   *math.HexOrDecimal256
    54  	GasLimit math.HexOrDecimal64
    55  	GasUsed  math.HexOrDecimal64
    56  	Time     math.HexOrDecimal64
    57  	Extra    hexutil.Bytes
    58  	BaseFee  *math.HexOrDecimal256
    59  }
    60  
    61  type bbInput struct {
    62  	Header      *header             `json:"header,omitempty"`
    63  	TxRlp       string              `json:"txs,omitempty"`
    64  	Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
    65  
    66  	Txs []*types.Transaction `json:"-"`
    67  }
    68  
    69  // ToBlock converts i into a *types.Block
    70  func (i *bbInput) ToBlock() *types.Block {
    71  	header := &types.Header{
    72  		ParentHash:      i.Header.ParentHash,
    73  		Coinbase:        common.Address{},
    74  		Root:            i.Header.Root,
    75  		TxHash:          types.EmptyTxsHash,
    76  		ReceiptHash:     types.EmptyReceiptsHash,
    77  		Bloom:           i.Header.Bloom,
    78  		Number:          i.Header.Number,
    79  		GasLimit:        i.Header.GasLimit,
    80  		GasUsed:         i.Header.GasUsed,
    81  		Time:            i.Header.Time,
    82  		Extra:           i.Header.Extra,
    83  		Random:          i.Header.Random,
    84  		BaseFee:         i.Header.BaseFee,
    85  		WithdrawalsHash: i.Header.WithdrawalsHash,
    86  	}
    87  
    88  	// Fill optional values.
    89  	if i.Header.Coinbase != nil {
    90  		header.Coinbase = *i.Header.Coinbase
    91  	}
    92  	if i.Header.TxHash != nil {
    93  		header.TxHash = *i.Header.TxHash
    94  	}
    95  	if i.Header.ReceiptHash != nil {
    96  		header.ReceiptHash = *i.Header.ReceiptHash
    97  	}
    98  	return types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: i.Txs, Withdrawals: i.Withdrawals})
    99  }
   100  
   101  // SealBlock seals the given block using the configured engine.
   102  func (i *bbInput) SealBlock(block *types.Block) (*types.Block, error) {
   103  	switch {
   104  	default:
   105  		return block, nil
   106  	}
   107  }
   108  
   109  // BuildBlock constructs a block from the given inputs.
   110  func BuildBlock(ctx *cli.Context) error {
   111  	// Configure the go-ethereum logger
   112  	glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
   113  	glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name)))
   114  	log.Root().SetHandler(glogger)
   115  
   116  	baseDir, err := createBasedir(ctx)
   117  	if err != nil {
   118  		return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
   119  	}
   120  	inputData, err := readInput(ctx)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	block := inputData.ToBlock()
   125  	block, err = inputData.SealBlock(block)
   126  	if err != nil {
   127  		return err
   128  	}
   129  	return dispatchBlock(ctx, baseDir, block)
   130  }
   131  
   132  func readInput(ctx *cli.Context) (*bbInput, error) {
   133  	var (
   134  		headerStr      = ctx.String(InputHeaderFlag.Name)
   135  		withdrawalsStr = ctx.String(InputWithdrawalsFlag.Name)
   136  		txsStr         = ctx.String(InputTxsRlpFlag.Name)
   137  		inputData      = &bbInput{}
   138  	)
   139  	if headerStr == stdinSelector || txsStr == stdinSelector {
   140  		decoder := json.NewDecoder(os.Stdin)
   141  		if err := decoder.Decode(inputData); err != nil {
   142  			return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err))
   143  		}
   144  	}
   145  	if headerStr != stdinSelector {
   146  		var env header
   147  		if err := readFile(headerStr, "header", &env); err != nil {
   148  			return nil, err
   149  		}
   150  		inputData.Header = &env
   151  	}
   152  	if withdrawalsStr != stdinSelector && withdrawalsStr != "" {
   153  		var withdrawals []*types.Withdrawal
   154  		if err := readFile(withdrawalsStr, "withdrawals", &withdrawals); err != nil {
   155  			return nil, err
   156  		}
   157  		inputData.Withdrawals = withdrawals
   158  	}
   159  	if txsStr != stdinSelector {
   160  		var txs string
   161  		if err := readFile(txsStr, "txs", &txs); err != nil {
   162  			return nil, err
   163  		}
   164  		inputData.TxRlp = txs
   165  	}
   166  	// Deserialize rlp txs
   167  	var (
   168  		txs = []*types.Transaction{}
   169  	)
   170  	if inputData.TxRlp != "" {
   171  		if err := rlp.DecodeBytes(common.FromHex(inputData.TxRlp), &txs); err != nil {
   172  			return nil, NewError(ErrorRlp, fmt.Errorf("unable to decode transaction from rlp data: %v", err))
   173  		}
   174  		inputData.Txs = txs
   175  	}
   176  
   177  	return inputData, nil
   178  }
   179  
   180  // dispatchBlock writes the output data to either stderr or stdout, or to the specified
   181  // files
   182  func dispatchBlock(ctx *cli.Context, baseDir string, block *types.Block) error {
   183  	raw, _ := rlp.EncodeToBytes(block)
   184  	type blockInfo struct {
   185  		Rlp  hexutil.Bytes `json:"rlp"`
   186  		Hash common.Hash   `json:"hash"`
   187  	}
   188  	enc := blockInfo{
   189  		Rlp:  raw,
   190  		Hash: block.Hash(),
   191  	}
   192  	b, err := json.MarshalIndent(enc, "", "  ")
   193  	if err != nil {
   194  		return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
   195  	}
   196  	switch dest := ctx.String(OutputBlockFlag.Name); dest {
   197  	case "stdout":
   198  		os.Stdout.Write(b)
   199  		os.Stdout.WriteString("\n")
   200  	case "stderr":
   201  		os.Stderr.Write(b)
   202  		os.Stderr.WriteString("\n")
   203  	default:
   204  		if err := saveFile(baseDir, dest, enc); err != nil {
   205  			return err
   206  		}
   207  	}
   208  	return nil
   209  }