github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/evm_state_reader.go (about) 1 package gossip 2 3 import ( 4 "math/big" 5 6 "github.com/unicornultrafoundation/go-helios/hash" 7 "github.com/unicornultrafoundation/go-helios/native/idx" 8 "github.com/unicornultrafoundation/go-u2u/common" 9 "github.com/unicornultrafoundation/go-u2u/core/state" 10 "github.com/unicornultrafoundation/go-u2u/core/types" 11 "github.com/unicornultrafoundation/go-u2u/params" 12 13 "github.com/unicornultrafoundation/go-u2u/evmcore" 14 "github.com/unicornultrafoundation/go-u2u/gossip/gasprice" 15 "github.com/unicornultrafoundation/go-u2u/u2u" 16 ) 17 18 type EvmStateReader struct { 19 *ServiceFeed 20 21 store *Store 22 gpo *gasprice.Oracle 23 } 24 25 func NewEvmStateReader(s *Store) *EvmStateReader { 26 return &EvmStateReader{ 27 store: s, 28 } 29 } 30 31 func (s *Service) GetEvmStateReader() *EvmStateReader { 32 return &EvmStateReader{ 33 ServiceFeed: &s.feed, 34 store: s.store, 35 gpo: s.gpo, 36 } 37 } 38 39 // MinGasPrice returns current hard lower bound for gas price 40 func (r *EvmStateReader) MinGasPrice() *big.Int { 41 return r.store.GetRules().Economy.MinGasPrice 42 } 43 44 // EffectiveMinTip returns current soft lower bound for gas tip 45 func (r *EvmStateReader) EffectiveMinTip() *big.Int { 46 min := r.MinGasPrice() 47 est := r.gpo.EffectiveMinGasPrice() 48 est.Sub(est, min) 49 if est.Sign() < 0 { 50 return new(big.Int) 51 } 52 return est 53 } 54 55 func (r *EvmStateReader) MaxGasLimit() uint64 { 56 rules := r.store.GetRules() 57 maxEmptyEventGas := rules.Economy.Gas.EventGas + 58 uint64(rules.Dag.MaxParents-rules.Dag.MaxFreeParents)*rules.Economy.Gas.ParentGas + 59 uint64(rules.Dag.MaxExtraData)*rules.Economy.Gas.ExtraDataGas 60 if rules.Economy.Gas.MaxEventGas < maxEmptyEventGas { 61 return 0 62 } 63 return rules.Economy.Gas.MaxEventGas - maxEmptyEventGas 64 } 65 66 func (r *EvmStateReader) Config() *params.ChainConfig { 67 return r.store.GetEvmChainConfig() 68 } 69 70 func (r *EvmStateReader) CurrentBlock() *evmcore.EvmBlock { 71 n := r.store.GetLatestBlockIndex() 72 73 return r.getBlock(hash.Event{}, n, true) 74 } 75 76 func (r *EvmStateReader) CurrentHeader() *evmcore.EvmHeader { 77 n := r.store.GetLatestBlockIndex() 78 79 return r.getBlock(hash.Event{}, n, false).Header() 80 } 81 82 func (r *EvmStateReader) GetHeader(h common.Hash, n uint64) *evmcore.EvmHeader { 83 return r.getBlock(hash.Event(h), idx.Block(n), false).Header() 84 } 85 86 func (r *EvmStateReader) GetBlock(h common.Hash, n uint64) *evmcore.EvmBlock { 87 return r.getBlock(hash.Event(h), idx.Block(n), true) 88 } 89 90 func (r *EvmStateReader) getBlock(h hash.Event, n idx.Block, readTxs bool) *evmcore.EvmBlock { 91 block := r.store.GetBlock(n) 92 if block == nil { 93 return nil 94 } 95 if (h != hash.Event{}) && (h != block.Atropos) { 96 return nil 97 } 98 if readTxs { 99 if cached := r.store.EvmStore().GetCachedEvmBlock(n); cached != nil { 100 return cached 101 } 102 } 103 104 var transactions types.Transactions 105 if readTxs { 106 transactions = r.store.GetBlockTxs(n, block) 107 } else { 108 transactions = make(types.Transactions, 0) 109 } 110 111 // find block rules 112 epoch := block.Atropos.Epoch() 113 es := r.store.GetHistoryEpochState(epoch) 114 var rules u2u.Rules 115 if es != nil { 116 rules = es.Rules 117 } 118 var prev hash.Event 119 if n != 0 { 120 block := r.store.GetBlock(n - 1) 121 if block != nil { 122 prev = block.Atropos 123 } 124 } 125 evmHeader := evmcore.ToEvmHeader(block, n, prev, rules) 126 127 var evmBlock *evmcore.EvmBlock 128 if readTxs { 129 evmBlock = evmcore.NewEvmBlock(evmHeader, transactions) 130 r.store.EvmStore().SetCachedEvmBlock(n, evmBlock) 131 } else { 132 // not completed block here 133 evmBlock = &evmcore.EvmBlock{ 134 EvmHeader: *evmHeader, 135 } 136 } 137 138 return evmBlock 139 } 140 141 func (r *EvmStateReader) StateAt(root common.Hash) (*state.StateDB, error) { 142 return r.store.evm.StateDB(hash.Hash(root)) 143 }