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  }