github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/gpo_backend.go (about)

     1  package gossip
     2  
     3  import (
     4  	"github.com/unicornultrafoundation/go-u2u/common"
     5  	"github.com/unicornultrafoundation/go-u2u/core/types"
     6  
     7  	"github.com/unicornultrafoundation/go-helios/hash"
     8  	"github.com/unicornultrafoundation/go-helios/native/idx"
     9  
    10  	"github.com/unicornultrafoundation/go-u2u/eventcheck/gaspowercheck"
    11  	"github.com/unicornultrafoundation/go-u2u/native"
    12  	"github.com/unicornultrafoundation/go-u2u/u2u"
    13  	"github.com/unicornultrafoundation/go-u2u/utils/concurrent"
    14  )
    15  
    16  type GPOBackend struct {
    17  	store  *Store
    18  	txpool TxPool
    19  }
    20  
    21  func (b *GPOBackend) GetLatestBlockIndex() idx.Block {
    22  	return b.store.GetLatestBlockIndex()
    23  }
    24  
    25  func (b *GPOBackend) GetRules() u2u.Rules {
    26  	return b.store.GetRules()
    27  }
    28  
    29  func (b *GPOBackend) GetPendingRules() u2u.Rules {
    30  	bs, es := b.store.GetBlockEpochState()
    31  	if bs.DirtyRules != nil {
    32  		return *bs.DirtyRules
    33  	}
    34  	return es.Rules
    35  }
    36  
    37  func (b *GPOBackend) PendingTxs() map[common.Address]types.Transactions {
    38  	txs, err := b.txpool.Pending(false)
    39  	if err != nil {
    40  		return map[common.Address]types.Transactions{}
    41  	}
    42  	return txs
    43  }
    44  
    45  // TotalGasPowerLeft returns a total amount of obtained gas power by the validators, according to the latest events from each validator
    46  func (b *GPOBackend) TotalGasPowerLeft() uint64 {
    47  	bs, es := b.store.GetBlockEpochState()
    48  	set := b.store.GetLastEvents(es.Epoch)
    49  	if set == nil {
    50  		set = concurrent.WrapValidatorEventsSet(map[idx.ValidatorID]hash.Event{})
    51  	}
    52  	set.RLock()
    53  	defer set.RUnlock()
    54  	metValidators := map[idx.ValidatorID]bool{}
    55  	total := uint64(0)
    56  	gasPowerCheckCfg := gaspowercheck.Config{
    57  		Idx:                native.LongTermGas,
    58  		AllocPerSec:        es.Rules.Economy.LongGasPower.AllocPerSec,
    59  		MaxAllocPeriod:     es.Rules.Economy.LongGasPower.MaxAllocPeriod,
    60  		MinEnsuredAlloc:    es.Rules.Economy.Gas.MaxEventGas,
    61  		StartupAllocPeriod: es.Rules.Economy.LongGasPower.StartupAllocPeriod,
    62  		MinStartupGas:      es.Rules.Economy.LongGasPower.MinStartupGas,
    63  	}
    64  	// count GasPowerLeft from latest events of this epoch
    65  	for _, tip := range set.Val {
    66  		e := b.store.GetEvent(tip)
    67  		left := e.GasPowerLeft().Gas[native.LongTermGas]
    68  		left += bs.GetValidatorState(e.Creator(), es.Validators).DirtyGasRefund
    69  
    70  		_, max, _ := gaspowercheck.CalcValidatorGasPowerPerSec(e.Creator(), es.Validators, gasPowerCheckCfg)
    71  		if left > max {
    72  			left = max
    73  		}
    74  		total += left
    75  
    76  		metValidators[e.Creator()] = true
    77  	}
    78  	// count GasPowerLeft from last events of prev epoch if no event in current epoch is present
    79  	for i := idx.Validator(0); i < es.Validators.Len(); i++ {
    80  		vid := es.Validators.GetID(i)
    81  		if !metValidators[vid] {
    82  			left := es.ValidatorStates[i].PrevEpochEvent.GasPowerLeft.Gas[native.LongTermGas]
    83  			left += es.ValidatorStates[i].GasRefund
    84  
    85  			_, max, startup := gaspowercheck.CalcValidatorGasPowerPerSec(vid, es.Validators, gasPowerCheckCfg)
    86  			if left > max {
    87  				left = max
    88  			}
    89  			if left < startup {
    90  				left = startup
    91  			}
    92  			total += left
    93  		}
    94  	}
    95  
    96  	return total
    97  }