@ -148,7 +148,7 @@ type BlockChain struct {
lastCommitsCache * lru . Cache
lastCommitsCache * lru . Cache
epochCache * lru . Cache // Cache epoch number → first block number
epochCache * lru . Cache // Cache epoch number → first block number
randomnessCache * lru . Cache // Cache for vrf/vdf
randomnessCache * lru . Cache // Cache for vrf/vdf
validatorCache * lru . Cache // Cache for validator info
validatorSnapshot Cache * lru . Cache // Cache for validator snapshot
validatorStatsCache * lru . Cache // Cache for validator stats
validatorStatsCache * lru . Cache // Cache for validator stats
validatorListCache * lru . Cache // Cache of validator list
validatorListCache * lru . Cache // Cache of validator list
validatorListByDelegatorCache * lru . Cache // Cache of validator list by delegator
validatorListByDelegatorCache * lru . Cache // Cache of validator list by delegator
@ -217,7 +217,7 @@ func NewBlockChain(
lastCommitsCache : commitsCache ,
lastCommitsCache : commitsCache ,
epochCache : epochCache ,
epochCache : epochCache ,
randomnessCache : randomnessCache ,
randomnessCache : randomnessCache ,
validatorCache : validatorCache ,
validatorSnapshot Cache : validatorCache ,
validatorStatsCache : validatorStatsCache ,
validatorStatsCache : validatorStatsCache ,
validatorListCache : validatorListCache ,
validatorListCache : validatorListCache ,
validatorListByDelegatorCache : validatorListByDelegatorCache ,
validatorListByDelegatorCache : validatorListByDelegatorCache ,
@ -2196,48 +2196,25 @@ func (bc *BlockChain) ReadValidatorSnapshot(
addr common . Address ,
addr common . Address ,
) ( * staking . ValidatorSnapshot , error ) {
) ( * staking . ValidatorSnapshot , error ) {
epoch := bc . CurrentBlock ( ) . Epoch ( )
epoch := bc . CurrentBlock ( ) . Epoch ( )
if cached , ok := bc . validatorCache . Get ( "validator-snapshot-" + string ( addr . Bytes ( ) ) + epoch . String ( ) ) ; ok {
key := addr . Hex ( ) + epoch . String ( )
by := cached . ( [ ] byte )
if cached , ok := bc . validatorSnapshotCache . Get ( key ) ; ok {
v := staking . ValidatorWrapper { }
return cached . ( * staking . ValidatorSnapshot ) , nil
if err := rlp . DecodeBytes ( by , & v ) ; err != nil {
return nil , err
}
s := staking . ValidatorSnapshot { & v , epoch }
return & s , nil
}
}
return rawdb . ReadValidatorSnapshot ( bc . db , addr , epoch )
return rawdb . ReadValidatorSnapshot ( bc . db , addr , epoch )
}
}
// writeValidatorSnapshots writes the snapshot of provided list of validators
// WriteValidatorSnapshot writes the snapshot of provided validator
func ( bc * BlockChain ) writeValidatorSnapshots (
func ( bc * BlockChain ) WriteValidatorSnapshot (
batch rawdb . DatabaseWriter , addrs [ ] common . Address , epoch * big . Int , state * state . DB ,
batch rawdb . DatabaseWriter , snapshot * staking . ValidatorSnapshot ,
) error {
) error {
// Read all validator's current data
validators := [ ] * staking . ValidatorWrapper { }
for i := range addrs {
// The snapshot will be captured in the state after the last epoch block is finalized
validator , err := state . ValidatorWrapper ( addrs [ i ] )
if err != nil {
return err
}
validators = append ( validators , validator )
}
// Batch write the current data as snapshot
// Batch write the current data as snapshot
for i := range validators {
if err := rawdb . WriteValidatorSnapshot ( batch , snapshot . Validator , snapshot . Epoch ) ; err != nil {
if err := rawdb . WriteValidatorSnapshot ( batch , validators [ i ] , epoch ) ; err != nil {
return err
return err
}
}
}
// Update cache
// Update cache
for i := range validators {
key := snapshot . Validator . Address . Hex ( ) + snapshot . Epoch . String ( )
by , err := rlp . EncodeToBytes ( validators [ i ] )
bc . validatorSnapshotCache . Add ( key , snapshot )
if err == nil {
key := "validator-snapshot-" + string ( validators [ i ] . Address . Bytes ( ) ) + epoch . String ( )
bc . validatorCache . Add ( key , by )
}
}
return nil
return nil
}
}
@ -2381,7 +2358,21 @@ func (bc *BlockChain) UpdateValidatorSnapshots(
allValidators = append ( allValidators , newValidators ... )
allValidators = append ( allValidators , newValidators ... )
return bc . writeValidatorSnapshots ( batch , allValidators , epoch , state )
// Read all validator's current data and snapshot them
for i := range allValidators {
// The snapshot will be captured in the state after the last epoch block is finalized
validator , err := state . ValidatorWrapper ( allValidators [ i ] )
if err != nil {
return err
}
snapshot := & staking . ValidatorSnapshot { validator , epoch }
if err := bc . WriteValidatorSnapshot ( batch , snapshot ) ; err != nil {
return err
}
}
return nil
}
}
// ReadValidatorList reads the addresses of current all validators
// ReadValidatorList reads the addresses of current all validators
@ -2494,13 +2485,13 @@ func (bc *BlockChain) UpdateStakingMetaData(
return newValidators , err
return newValidators , err
}
}
if err := rawd b. WriteValidatorSnapshot ( batch , validator , epoch ) ; err != nil {
if err := bc . WriteValidatorSnapshot ( batch , & staking . ValidatorSnapshot { validator , epoch } ) ; err != nil {
return newValidators , err
return newValidators , err
}
}
// For validator created at exactly the last block of an epoch, we should create the snapshot
// For validator created at exactly the last block of an epoch, we should create the snapshot
// for next epoch too.
// for next epoch too.
if newEpoch . Cmp ( epoch ) > 0 {
if newEpoch . Cmp ( epoch ) > 0 {
if err := rawd b. WriteValidatorSnapshot ( batch , validator , newEpoch ) ; err != nil {
if err := bc . WriteValidatorSnapshot ( batch , & staking . ValidatorSnapshot { validator , newEpoch } ) ; err != nil {
return newValidators , err
return newValidators , err
}
}
}
}