|
|
|
@ -51,6 +51,8 @@ import ( |
|
|
|
|
"github.com/harmony-one/harmony/shard" |
|
|
|
|
"github.com/harmony-one/harmony/shard/committee" |
|
|
|
|
"github.com/harmony-one/harmony/staking/apr" |
|
|
|
|
"github.com/harmony-one/harmony/staking/availability" |
|
|
|
|
"github.com/harmony-one/harmony/staking/effective" |
|
|
|
|
"github.com/harmony-one/harmony/staking/slash" |
|
|
|
|
staking "github.com/harmony-one/harmony/staking/types" |
|
|
|
|
lru "github.com/hashicorp/golang-lru" |
|
|
|
@ -2289,7 +2291,29 @@ func (bc *BlockChain) UpdateValidatorVotingPower( |
|
|
|
|
return shard.ErrSuperCommitteeNil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rosters := make([]*votepower.Roster, len(newEpochSuperCommittee.Shards)) |
|
|
|
|
rosters, bootedFromSuperCommittee := |
|
|
|
|
make([]*votepower.Roster, len(newEpochSuperCommittee.Shards)), |
|
|
|
|
map[common.Address]struct{}{} |
|
|
|
|
|
|
|
|
|
existing, replacing := |
|
|
|
|
currentEpochSuperCommittee.StakedValidators(), |
|
|
|
|
newEpochSuperCommittee.StakedValidators() |
|
|
|
|
|
|
|
|
|
// TODO could also keep track of the BLS keys which
|
|
|
|
|
// lost a slot because just losing slots doesn't mean that the
|
|
|
|
|
// validator was booted, just that some of their keys lost slots
|
|
|
|
|
|
|
|
|
|
for currentValidator := range existing.LookupSet { |
|
|
|
|
if _, keptSlot := replacing.LookupSet[currentValidator]; !keptSlot { |
|
|
|
|
bootedFromSuperCommittee[currentValidator] = struct{}{} |
|
|
|
|
// NOTE Think carefully about when time comes to delete offchain things
|
|
|
|
|
// TODO Someone: collect and then delete every 30 epochs
|
|
|
|
|
// rawdb.DeleteValidatorSnapshot(
|
|
|
|
|
// bc.db, currentValidator, currentEpochSuperCommittee.Epoch,
|
|
|
|
|
// )
|
|
|
|
|
// rawdb.DeleteValidatorStats(bc.db, currentValidator)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for i := range newEpochSuperCommittee.Shards { |
|
|
|
|
subCommittee := &newEpochSuperCommittee.Shards[i] |
|
|
|
@ -2307,7 +2331,9 @@ func (bc *BlockChain) UpdateValidatorVotingPower( |
|
|
|
|
} |
|
|
|
|
rosters[i] = roster |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
networkWide := votepower.AggregateRosters(rosters) |
|
|
|
|
|
|
|
|
|
for key, value := range networkWide { |
|
|
|
|
stats, err := rawdb.ReadValidatorStats(bc.db, key) |
|
|
|
|
if err != nil { |
|
|
|
@ -2347,45 +2373,55 @@ func (bc *BlockChain) UpdateValidatorVotingPower( |
|
|
|
|
utils.Logger().Debug().Err(err).Msg("issue with compute of apr") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if err := rawdb.WriteValidatorStats( |
|
|
|
|
batch, key, stats, |
|
|
|
|
); err != nil { |
|
|
|
|
snapshot, err := bc.ReadValidatorSnapshotAtEpoch( |
|
|
|
|
currentEpochSuperCommittee.Epoch, wrapper.Address, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
existing, replacing := |
|
|
|
|
currentEpochSuperCommittee.StakedValidators(), |
|
|
|
|
newEpochSuperCommittee.StakedValidators() |
|
|
|
|
for currentValidator := range existing.LookupSet { |
|
|
|
|
if _, keptSlot := replacing.LookupSet[currentValidator]; !keptSlot { |
|
|
|
|
// TODO Someone: collect and then delete every 30 epochs
|
|
|
|
|
// rawdb.DeleteValidatorSnapshot(
|
|
|
|
|
// bc.db, currentValidator, currentEpochSuperCommittee.Epoch,
|
|
|
|
|
// )
|
|
|
|
|
rawdb.DeleteValidatorStats(bc.db, currentValidator) |
|
|
|
|
} |
|
|
|
|
computed := availability.ComputeCurrentSigning(snapshot, wrapper) |
|
|
|
|
|
|
|
|
|
if _, wasBooted := bootedFromSuperCommittee[wrapper.Address]; wasBooted { |
|
|
|
|
stats.BootedStatus = effective.LostEPoSAuction |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
if computed.IsBelowThreshold { |
|
|
|
|
stats.BootedStatus = effective.InsufficientUptimeDuringEpoch |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// deleteValidatorSnapshots deletes the snapshot staking information of given validator address
|
|
|
|
|
// TODO: delete validator snapshots from X epochs ago
|
|
|
|
|
func (bc *BlockChain) deleteValidatorSnapshots(addrs []common.Address) error { |
|
|
|
|
batch := bc.db.NewBatch() |
|
|
|
|
for i := range addrs { |
|
|
|
|
rawdb.DeleteValidatorSnapshot(batch, addrs[i], bc.CurrentBlock().Epoch()) |
|
|
|
|
if slash.IsBanned(wrapper) { |
|
|
|
|
stats.BootedStatus = effective.BannedForDoubleSigning |
|
|
|
|
} |
|
|
|
|
if err := batch.Write(); err != nil { |
|
|
|
|
|
|
|
|
|
if err := rawdb.WriteValidatorStats( |
|
|
|
|
batch, key, stats, |
|
|
|
|
); err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
for i := range addrs { |
|
|
|
|
bc.validatorCache.Remove("validator-snapshot-" + string(addrs[i].Bytes())) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// deleteValidatorSnapshots deletes the snapshot staking information of given validator address
|
|
|
|
|
// TODO: delete validator snapshots from X epochs ago
|
|
|
|
|
// NOTE Use when needed but don't compile at all until then
|
|
|
|
|
// func (bc *BlockChain) deleteValidatorSnapshots(addrs []common.Address) error {
|
|
|
|
|
// batch := bc.db.NewBatch()
|
|
|
|
|
// for i := range addrs {
|
|
|
|
|
// rawdb.DeleteValidatorSnapshot(batch, addrs[i], bc.CurrentBlock().Epoch())
|
|
|
|
|
// }
|
|
|
|
|
// if err := batch.Write(); err != nil {
|
|
|
|
|
// return err
|
|
|
|
|
// }
|
|
|
|
|
// for i := range addrs {
|
|
|
|
|
// bc.validatorCache.Remove("validator-snapshot-" + string(addrs[i].Bytes()))
|
|
|
|
|
// }
|
|
|
|
|
// return nil
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// UpdateValidatorSnapshots updates the content snapshot of all validators
|
|
|
|
|
// Note: this should only be called within the blockchain insert process.
|
|
|
|
|
func (bc *BlockChain) UpdateValidatorSnapshots( |
|
|
|
|