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 }