github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/blockproc/evmmodule/evm.go (about) 1 package evmmodule 2 3 import ( 4 "math" 5 "math/big" 6 7 "github.com/unicornultrafoundation/go-u2u/common" 8 "github.com/unicornultrafoundation/go-u2u/core/state" 9 "github.com/unicornultrafoundation/go-u2u/core/types" 10 "github.com/unicornultrafoundation/go-u2u/log" 11 "github.com/unicornultrafoundation/go-u2u/params" 12 13 "github.com/unicornultrafoundation/go-u2u/evmcore" 14 "github.com/unicornultrafoundation/go-u2u/gossip/blockproc" 15 "github.com/unicornultrafoundation/go-u2u/native" 16 "github.com/unicornultrafoundation/go-u2u/native/iblockproc" 17 "github.com/unicornultrafoundation/go-u2u/u2u" 18 "github.com/unicornultrafoundation/go-u2u/utils" 19 ) 20 21 type EVMModule struct{} 22 23 func New() *EVMModule { 24 return &EVMModule{} 25 } 26 27 func (p *EVMModule) Start(block iblockproc.BlockCtx, statedb *state.StateDB, reader evmcore.DummyChain, onNewLog func(*types.Log), net u2u.Rules, evmCfg *params.ChainConfig) blockproc.EVMProcessor { 28 var prevBlockHash common.Hash 29 if block.Idx != 0 { 30 prevBlockHash = reader.GetHeader(common.Hash{}, uint64(block.Idx-1)).Hash 31 } 32 return &U2UEVMProcessor{ 33 block: block, 34 reader: reader, 35 statedb: statedb, 36 onNewLog: onNewLog, 37 net: net, 38 evmCfg: evmCfg, 39 blockIdx: utils.U64toBig(uint64(block.Idx)), 40 prevBlockHash: prevBlockHash, 41 } 42 } 43 44 type U2UEVMProcessor struct { 45 block iblockproc.BlockCtx 46 reader evmcore.DummyChain 47 statedb *state.StateDB 48 onNewLog func(*types.Log) 49 net u2u.Rules 50 evmCfg *params.ChainConfig 51 52 blockIdx *big.Int 53 prevBlockHash common.Hash 54 55 gasUsed uint64 56 57 incomingTxs types.Transactions 58 skippedTxs []uint32 59 receipts types.Receipts 60 } 61 62 func (p *U2UEVMProcessor) evmBlockWith(txs types.Transactions) *evmcore.EvmBlock { 63 baseFee := p.net.Economy.MinGasPrice 64 if !p.net.Upgrades.London { 65 baseFee = nil 66 } 67 h := &evmcore.EvmHeader{ 68 Number: p.blockIdx, 69 Hash: common.Hash(p.block.Atropos), 70 ParentHash: p.prevBlockHash, 71 Root: common.Hash{}, 72 Time: p.block.Time, 73 Coinbase: common.Address{}, 74 GasLimit: math.MaxUint64, 75 GasUsed: p.gasUsed, 76 BaseFee: baseFee, 77 } 78 79 return evmcore.NewEvmBlock(h, txs) 80 } 81 82 func (p *U2UEVMProcessor) Execute(txs types.Transactions) types.Receipts { 83 evmProcessor := evmcore.NewStateProcessor(p.evmCfg, p.reader) 84 txsOffset := uint(len(p.incomingTxs)) 85 86 // Process txs 87 evmBlock := p.evmBlockWith(txs) 88 receipts, _, skipped, err := evmProcessor.Process(evmBlock, p.statedb, u2u.DefaultVMConfig, &p.gasUsed, func(l *types.Log, _ *state.StateDB) { 89 // Note: l.Index is properly set before 90 l.TxIndex += txsOffset 91 p.onNewLog(l) 92 }) 93 if err != nil { 94 log.Crit("EVM internal error", "err", err) 95 } 96 97 if txsOffset > 0 { 98 for i, n := range skipped { 99 skipped[i] = n + uint32(txsOffset) 100 } 101 for _, r := range receipts { 102 r.TransactionIndex += txsOffset 103 } 104 } 105 106 p.incomingTxs = append(p.incomingTxs, txs...) 107 p.skippedTxs = append(p.skippedTxs, skipped...) 108 p.receipts = append(p.receipts, receipts...) 109 110 return receipts 111 } 112 113 func (p *U2UEVMProcessor) Finalize() (evmBlock *evmcore.EvmBlock, skippedTxs []uint32, receipts types.Receipts) { 114 evmBlock = p.evmBlockWith( 115 // Filter skipped transactions. Receipts are filtered already 116 native.FilterSkippedTxs(p.incomingTxs, p.skippedTxs), 117 ) 118 skippedTxs = p.skippedTxs 119 receipts = p.receipts 120 121 // Get state root 122 newStateHash, err := p.statedb.Commit(true) 123 if err != nil { 124 log.Crit("Failed to commit state", "err", err) 125 } 126 evmBlock.Root = newStateHash 127 128 return 129 }