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  }