github.com/hxy-daniel/soda-study@v0.0.0-20210825114314-29b7dcb300f1/SODA_code/go-ethereum/core/state_processor.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser 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 // The go-ethereum library 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 Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/consensus" 22 "github.com/ethereum/go-ethereum/consensus/misc" 23 "github.com/ethereum/go-ethereum/core/state" 24 "github.com/ethereum/go-ethereum/core/types" 25 "github.com/ethereum/go-ethereum/core/vm" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/params" 28 //add new 29 "github.com/ethereum/collector" 30 // "syscall" 31 "strconv" 32 "fmt" 33 "github.com/ethereum/go-ethereum/tingrong" 34 "github.com/ethereum/go-ethereum/cmd/pluginManage" 35 "github.com/ethereum/go-ethereum/fei" 36 ) 37 38 // StateProcessor is a basic Processor, which takes care of transitioning 39 // state from one point to another. 40 // 41 // StateProcessor implements Processor. 42 type StateProcessor struct { 43 config *params.ChainConfig // Chain configuration options 44 bc *BlockChain // Canonical block chain 规范区块链 45 engine consensus.Engine // Consensus engine used for block rewards 46 } 47 48 // NewStateProcessor initialises a new StateProcessor. 49 func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { 50 return &StateProcessor{ 51 config: config, 52 bc: bc, 53 engine: engine, 54 } 55 } 56 57 // Process processes the state changes according to the Ethereum rules by running 58 // the transaction messages using the statedb and applying any rewards to both 59 // the processor (coinbase) and any included uncles. 60 // 61 // Process returns the receipts and logs accumulated during the process and 62 // returns the amount of gas that was used in the process. If any of the 63 // transactions failed to execute due to insufficient gas it will return an error. 64 func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { 65 var ( 66 receipts types.Receipts 67 usedGas = new(uint64) 68 header = block.Header() 69 allLogs []*types.Log 70 gp = new(GasPool).AddGas(block.GasLimit()) 71 ) 72 // Mutate the block and state according to any hard-fork specs / 根据任何硬分叉规范改变块和状态 73 if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { 74 misc.ApplyDAOHardFork(statedb) 75 } 76 77 //add new 78 // 区块收集器 79 // 如果plg.plugins[handle_BLOCK_INFO]存在,即需要该信息 80 if p.config.TransferDataPlg.GetOpcodeRegister("handle_BLOCK_INFO"){ 81 blockcollector := collector.NewBlockCollector() 82 blockcollector.Op = "Block"+fmt.Sprintf("%v", header.Number) 83 blockcollector.ParentHash = header.ParentHash.String() 84 blockcollector.UncleHash = header.UncleHash.String() 85 blockcollector.Coinbase = header.Coinbase.String() 86 blockcollector.StateRoot = header.Root.String() 87 blockcollector.TxHashRoot = header.TxHash.String() 88 blockcollector.ReceiptHash = header.ReceiptHash.String() 89 blockcollector.Difficulty = header.Difficulty.String() 90 blockcollector.Number = header.Number.String() 91 blockcollector.GasLimit = header.GasLimit 92 blockcollector.GasUsed = header.GasUsed 93 blockcollector.Time = header.Time 94 blockcollector.Extra = header.Extra 95 blockcollector.MixDigest = header.MixDigest.String() 96 blockcollector.Nonce = header.Nonce.Uint64() 97 98 // TransferDataPlg:/cmd/pluginManage/pluginManage.go/PluginManages 即调用PluginManages的SendDataToPlugin()函数 99 p.config.TransferDataPlg.SendDataToPlugin("handle_BLOCK_INFO",blockcollector.SendBlockInfo("handle_BLOCK_INFO")) 100 } 101 //add new 102 103 // Iterate over and process the individual transactions 104 for i, tx := range block.Transactions() { 105 statedb.Prepare(tx.Hash(), block.Hash(), i) 106 receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) 107 if err != nil { 108 return nil, nil, 0, err 109 } 110 receipts = append(receipts, receipt) 111 allLogs = append(allLogs, receipt.Logs...) 112 } 113 114 115 116 // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) / 完成区块,应用任何共识引擎特定的附加功能(比如区块奖励) 117 p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) 118 119 return receipts, allLogs, *usedGas, nil 120 } 121 122 // ApplyTransaction attempts to apply a transaction to the given state database 123 // and uses the input parameters for its environment. It returns the receipt 124 // for the transaction, gas used and an error if the transaction failed, 125 // indicating the block was invalid. 126 func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { 127 msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) 128 if err != nil { 129 return nil, 0, err 130 } 131 132 // Create a new context to be used in the EVM environment 133 context := NewEVMContext(msg, header, bc, author) 134 // Create a new environment which holds all relevant information 135 // about the transaction and calling mechanisms. 136 vmenv := vm.NewEVM(context, statedb, config, cfg) 137 138 //add new 139 // 交易收集器:外部交易,SODA_code/go-ethereum/core/vm/interpreter.go/和SODA_code/go-ethereum/core/vm/instructions.go中还有内部交易 140 vmenv.SetTxStart(true) 141 vmenv.ChainConfig().TransferDataPlg.Start() 142 143 //feifei add new --api 144 if fei.IsReg { 145 // //whole folder fresh有问题,如果全部移除,是无法删掉旧的的。需要用new去新增 146 // pluginManage.StartRun(vmenv.ChainConfig().TransferDataPlg) 147 // fei.IsReg = false 148 149 //single plugin 150 pluginManage.RegisterPlugin(vmenv.ChainConfig().TransferDataPlg, fei.RegPath) 151 fei.RegPath = fei.Clear 152 fei.IsReg = false 153 } 154 155 if fei.IsUn { 156 vmenv.ChainConfig().TransferDataPlg.UnRegisterPlg() 157 fei.IsUn = false 158 fei.UnPlg = fei.Clear 159 } 160 161 tingrong.CALL_LAYER = 0 162 tingrong.CALL_STACK = nil 163 tingrong.ALL_STACK = nil 164 tingrong.EXTERNAL_FLAG = true 165 tingrong.BLOCKING_FLAG = false 166 tingrong.PLUGIN_SNAPSHOT_ID = 0 167 tingrong.CALLVALID_MAP = make(map[int]bool) 168 tingrong.TxHash = tx.Hash().String() 169 170 // if vmenv.BlockNumber.Int64() >= 2300001{ 171 // if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("ENDSIGNAL") { 172 // vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("ENDSIGNAL", collector.SendFlag("ENDSIGNAL")) 173 // } 174 // fmt.Println("!!!!!!!!!!!!!! ", vmenv.BlockNumber, " EXIT") 175 // syscall.Kill(syscall.Getpid(), syscall.SIGINT) 176 // } 177 178 179 if msg.To() != nil{ 180 tingrong.CALL_LAYER += 1 181 tingrong.CALL_STACK = append(tingrong.CALL_STACK,msg.To().String()+"#"+strconv.Itoa(tingrong.CALL_LAYER)) 182 tingrong.ALL_STACK = append(tingrong.ALL_STACK,msg.To().String()) 183 } 184 185 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("TXSTART"){ 186 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("TXSTART", collector.SendFlag("TXSTART")) 187 } 188 189 tcstart := collector.NewTransCollector() 190 191 //external collector 192 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOSTART"){ 193 tcstart.Op = "EXTERNALINFOSTART" 194 tcstart.TxHash = tx.Hash().String() 195 tcstart.BlockNumber = vmenv.BlockNumber.String() 196 tcstart.BlockTime = vmenv.Time.String() 197 tcstart.From = msg.From().String() 198 tcstart.Value = msg.Value().String() 199 tcstart.GasPrice = msg.GasPrice().String() 200 tcstart.GasLimit = msg.Gas() 201 tcstart.Nonce = tx.Nonce() 202 tcstart.CallLayer = 1 203 if msg.To() != nil { 204 tcstart.CallType = "CALL" 205 tcstart.To = msg.To().String() 206 207 callcollector := collector.NewCallCollector() 208 if vmenv.StateDB.Exist(*msg.To()) { 209 callcollector.ContractCode = vmenv.StateDB.GetCode(*msg.To()) 210 } 211 callcollector.InputData = msg.Data() 212 tcstart.CallInfo = *callcollector 213 } 214 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("EXTERNALINFOSTART", tcstart.SendTransInfo("EXTERNALINFOSTART")) 215 216 } 217 218 219 //add new 220 221 // Apply the transaction to the current state (included in the env) 222 _, gas, failed, err := ApplyMessage(vmenv, msg, gp) 223 224 225 //add new 226 if tingrong.BLOCKING_FLAG == true{ 227 statedb.RevertToSnapshot(tingrong.PLUGIN_SNAPSHOT_ID) 228 } 229 //add new 230 231 232 tcend := collector.NewTransCollector() 233 234 //add new 235 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOEND"){ 236 tcend.Op = "EXTERNALINFOEND" 237 tcend.TxHash = tx.Hash().String() 238 tcend.GasUsed = gas 239 tcend.CallLayer = 1 240 } 241 //add new 242 243 if err != nil { 244 //add new 245 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOEND"){ 246 tcend.IsSuccess = false 247 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("EXTERNALINFOEND", tcend.SendTransInfo("EXTERNALINFOEND")) 248 } 249 //add new 250 return nil, 0, err 251 } 252 // Update the state with pending changes 253 var root []byte 254 if config.IsByzantium(header.Number) { 255 statedb.Finalise(true) 256 } else { 257 root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() 258 } 259 *usedGas += gas 260 261 // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx 262 // based on the eip phase, we're passing whether the root touch-delete accounts. 263 receipt := types.NewReceipt(root, failed, *usedGas) 264 receipt.TxHash = tx.Hash() 265 receipt.GasUsed = gas 266 // if the transaction created a contract, store the creation address in the receipt. 267 if msg.To() == nil { 268 receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) 269 //add new 270 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOEND"){ 271 tcend.CallType = "CREATE" 272 tcend.To = receipt.ContractAddress.String() 273 createcollector := collector.NewCreateCollector() 274 createcollector.ContractAddr = receipt.ContractAddress.String() 275 createcollector.ContractDeployCode = msg.Data() 276 if vmenv.StateDB.Exist(receipt.ContractAddress) { 277 createcollector.ContractRuntimeCode = vmenv.StateDB.GetCode(receipt.ContractAddress) 278 } 279 tcend.CreateInfo = *createcollector 280 } 281 //add new 282 } 283 // Set the receipt logs and create a bloom for filtering 284 receipt.Logs = statedb.GetLogs(tx.Hash()) 285 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 286 receipt.BlockHash = statedb.BlockHash() 287 receipt.BlockNumber = header.Number 288 receipt.TransactionIndex = uint(statedb.TxIndex()) 289 290 //add new 291 if !failed { 292 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOEND"){ 293 tcend.IsSuccess = true 294 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("EXTERNALINFOEND", tcend.SendTransInfo("EXTERNALINFOEND")) 295 } 296 } else { 297 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("EXTERNALINFOEND"){ 298 tcend.IsSuccess = false 299 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("EXTERNALINFOEND", tcend.SendTransInfo("EXTERNALINFOEND")) 300 } 301 } 302 303 tingrong.CALL_STACK = tingrong.CALL_STACK[:len(tingrong.CALL_STACK)-1] 304 305 if vmenv.ChainConfig().TransferDataPlg.GetOpcodeRegister("TXEND"){ 306 vmenv.ChainConfig().TransferDataPlg.SendDataToPlugin("TXEND", collector.SendFlag("TXEND")) 307 vmenv.ChainConfig().TransferDataPlg.Stop() 308 } 309 310 311 //add new 312 313 return receipt, gas, err 314 }