github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/blockproc/sealmodule/sealer.go (about) 1 package sealmodule 2 3 import ( 4 "math/big" 5 6 "github.com/unicornultrafoundation/go-helios/native/idx" 7 "github.com/unicornultrafoundation/go-helios/native/pos" 8 "github.com/unicornultrafoundation/go-helios/types" 9 "github.com/unicornultrafoundation/go-u2u/gossip/blockproc" 10 "github.com/unicornultrafoundation/go-u2u/native/iblockproc" 11 ) 12 13 type U2UEpochsSealerModule struct{} 14 15 func New() *U2UEpochsSealerModule { 16 return &U2UEpochsSealerModule{} 17 } 18 19 func (m *U2UEpochsSealerModule) Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState) blockproc.SealerProcessor { 20 return &U2UEpochsSealer{ 21 block: block, 22 es: es, 23 bs: bs, 24 } 25 } 26 27 type U2UEpochsSealer struct { 28 block iblockproc.BlockCtx 29 es iblockproc.EpochState 30 bs iblockproc.BlockState 31 } 32 33 func (s *U2UEpochsSealer) EpochSealing() bool { 34 sealEpoch := s.bs.EpochGas >= s.es.Rules.Epochs.MaxEpochGas 35 sealEpoch = sealEpoch || (s.block.Time-s.es.EpochStart) >= s.es.Rules.Epochs.MaxEpochDuration 36 sealEpoch = sealEpoch || s.bs.AdvanceEpochs > 0 37 return sealEpoch || s.bs.EpochCheaters.Len() != 0 38 } 39 40 func (p *U2UEpochsSealer) Update(bs iblockproc.BlockState, es iblockproc.EpochState) { 41 p.bs, p.es = bs, es 42 } 43 44 // SealEpoch is called after pre-internal transactions are executed 45 func (s *U2UEpochsSealer) SealEpoch() (iblockproc.BlockState, iblockproc.EpochState) { 46 // Select new validators 47 oldValidators := s.es.Validators 48 builder := pos.NewBigBuilder() 49 for v, profile := range s.bs.NextValidatorProfiles { 50 builder.Set(v, profile.Weight) 51 } 52 newValidators := builder.Build() 53 s.es.Validators = newValidators 54 s.es.ValidatorProfiles = s.bs.NextValidatorProfiles.Copy() 55 56 // Build new []ValidatorEpochState and []ValidatorBlockState 57 newValidatorEpochStates := make([]iblockproc.ValidatorEpochState, newValidators.Len()) 58 newValidatorBlockStates := make([]iblockproc.ValidatorBlockState, newValidators.Len()) 59 for newValIdx := idx.Validator(0); newValIdx < newValidators.Len(); newValIdx++ { 60 // default values 61 newValidatorBlockStates[newValIdx] = iblockproc.ValidatorBlockState{ 62 Originated: new(big.Int), 63 } 64 // inherit validator's state from previous epoch, if any 65 valID := newValidators.GetID(newValIdx) 66 if !oldValidators.Exists(valID) { 67 // new validator 68 newValidatorBlockStates[newValIdx].LastBlock = s.block.Idx 69 newValidatorBlockStates[newValIdx].LastOnlineTime = s.block.Time 70 continue 71 } 72 oldValIdx := oldValidators.GetIdx(valID) 73 newValidatorBlockStates[newValIdx] = s.bs.ValidatorStates[oldValIdx] 74 newValidatorBlockStates[newValIdx].DirtyGasRefund = 0 75 newValidatorBlockStates[newValIdx].Uptime = 0 76 newValidatorEpochStates[newValIdx].GasRefund = s.bs.ValidatorStates[oldValIdx].DirtyGasRefund 77 newValidatorEpochStates[newValIdx].PrevEpochEvent = s.bs.ValidatorStates[oldValIdx].LastEvent 78 } 79 s.es.ValidatorStates = newValidatorEpochStates 80 s.bs.ValidatorStates = newValidatorBlockStates 81 s.es.Validators = newValidators 82 83 // dirty data becomes active 84 s.es.PrevEpochStart = s.es.EpochStart 85 s.es.EpochStart = s.block.Time 86 if s.bs.DirtyRules != nil { 87 s.es.Rules = s.bs.DirtyRules.Copy() 88 s.bs.DirtyRules = nil 89 } 90 s.es.EpochStateRoot = s.bs.FinalizedStateRoot 91 92 s.bs.EpochGas = 0 93 s.bs.EpochCheaters = types.Cheaters{} 94 s.bs.CheatersWritten = 0 95 newEpoch := s.es.Epoch + 1 96 s.es.Epoch = newEpoch 97 98 if s.bs.AdvanceEpochs > 0 { 99 s.bs.AdvanceEpochs-- 100 } 101 102 return s.bs, s.es 103 }