github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/eventcheck/epochcheck/epoch_check.go (about)

     1  package epochcheck
     2  
     3  import (
     4  	"errors"
     5  
     6  	base "github.com/unicornultrafoundation/go-helios/eventcheck/epochcheck"
     7  	"github.com/unicornultrafoundation/go-helios/native/idx"
     8  	"github.com/unicornultrafoundation/go-u2u/core/types"
     9  
    10  	"github.com/unicornultrafoundation/go-u2u/native"
    11  	"github.com/unicornultrafoundation/go-u2u/u2u"
    12  )
    13  
    14  var (
    15  	ErrTooManyParents    = errors.New("event has too many parents")
    16  	ErrTooBigGasUsed     = errors.New("event uses too much gas power")
    17  	ErrWrongGasUsed      = errors.New("event has incorrect gas power")
    18  	ErrUnderpriced       = errors.New("event transaction underpriced")
    19  	ErrTooBigExtra       = errors.New("event extra data is too large")
    20  	ErrWrongVersion      = errors.New("event has wrong version")
    21  	ErrUnsupportedTxType = errors.New("unsupported tx type")
    22  	ErrNotRelevant       = base.ErrNotRelevant
    23  	ErrAuth              = base.ErrAuth
    24  )
    25  
    26  // Reader returns currents epoch and its validators group.
    27  type Reader interface {
    28  	base.Reader
    29  	GetEpochRules() (u2u.Rules, idx.Epoch)
    30  }
    31  
    32  // Checker which require only current epoch info
    33  type Checker struct {
    34  	Base   *base.Checker
    35  	reader Reader
    36  }
    37  
    38  func New(reader Reader) *Checker {
    39  	return &Checker{
    40  		Base:   base.New(reader),
    41  		reader: reader,
    42  	}
    43  }
    44  
    45  func CalcGasPowerUsed(e native.EventPayloadI, rules u2u.Rules) uint64 {
    46  	txsGas := uint64(0)
    47  	for _, tx := range e.Txs() {
    48  		txsGas += tx.Gas()
    49  	}
    50  
    51  	gasCfg := rules.Economy.Gas
    52  
    53  	parentsGas := uint64(0)
    54  	if idx.Event(len(e.Parents())) > rules.Dag.MaxFreeParents {
    55  		parentsGas = uint64(idx.Event(len(e.Parents()))-rules.Dag.MaxFreeParents) * gasCfg.ParentGas
    56  	}
    57  	extraGas := uint64(len(e.Extra())) * gasCfg.ExtraDataGas
    58  
    59  	mpsGas := uint64(len(e.MisbehaviourProofs())) * gasCfg.MisbehaviourProofGas
    60  
    61  	bvsGas := uint64(0)
    62  	if e.BlockVotes().Start != 0 {
    63  		bvsGas = gasCfg.BlockVotesBaseGas + uint64(len(e.BlockVotes().Votes))*gasCfg.BlockVoteGas
    64  	}
    65  
    66  	ersGas := uint64(0)
    67  	if e.EpochVote().Epoch != 0 {
    68  		ersGas = gasCfg.EpochVoteGas
    69  	}
    70  
    71  	return txsGas + parentsGas + extraGas + gasCfg.EventGas + mpsGas + bvsGas + ersGas
    72  }
    73  
    74  func (v *Checker) checkGas(e native.EventPayloadI, rules u2u.Rules) error {
    75  	if e.GasPowerUsed() > rules.Economy.Gas.MaxEventGas {
    76  		return ErrTooBigGasUsed
    77  	}
    78  	if e.GasPowerUsed() != CalcGasPowerUsed(e, rules) {
    79  		return ErrWrongGasUsed
    80  	}
    81  	return nil
    82  }
    83  
    84  func CheckTxs(txs types.Transactions, rules u2u.Rules) error {
    85  	maxType := uint8(0)
    86  	if rules.Upgrades.Berlin {
    87  		maxType = 1
    88  	}
    89  	if rules.Upgrades.London {
    90  		maxType = 2
    91  	}
    92  	for _, tx := range txs {
    93  		if tx.Type() > maxType {
    94  			return ErrUnsupportedTxType
    95  		}
    96  		if tx.GasFeeCapIntCmp(rules.Economy.MinGasPrice) < 0 {
    97  			return ErrUnderpriced
    98  		}
    99  	}
   100  	return nil
   101  }
   102  
   103  // Validate event
   104  func (v *Checker) Validate(e native.EventPayloadI) error {
   105  	if err := v.Base.Validate(e); err != nil {
   106  		return err
   107  	}
   108  	rules, epoch := v.reader.GetEpochRules()
   109  	// Check epoch of the rules to prevent a race condition
   110  	if e.Epoch() != epoch {
   111  		return base.ErrNotRelevant
   112  	}
   113  	if idx.Event(len(e.Parents())) > rules.Dag.MaxParents {
   114  		return ErrTooManyParents
   115  	}
   116  	if uint32(len(e.Extra())) > rules.Dag.MaxExtraData {
   117  		return ErrTooBigExtra
   118  	}
   119  	if err := v.checkGas(e, rules); err != nil {
   120  		return err
   121  	}
   122  	if err := CheckTxs(e.Txs(), rules); err != nil {
   123  		return err
   124  	}
   125  	version := uint8(0)
   126  	if rules.Upgrades.Llr {
   127  		version = 1
   128  	}
   129  	if e.Version() != version {
   130  		return ErrWrongVersion
   131  	}
   132  	return nil
   133  }