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 }