Skip to content

Commit

Permalink
calculate uptime using the stored values
Browse files Browse the repository at this point in the history
  • Loading branch information
gakonst committed Nov 20, 2019
1 parent c476eff commit 1bb1ac0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
5 changes: 5 additions & 0 deletions consensus/istanbul/backend/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ func (sb *Backend) EpochSize() uint64 {
return sb.config.Epoch
}

// Returns the size of the lookback window for calculating uptime (in blocks)
func (sb *Backend) LookbackWindow() uint64 {
return sb.config.LookbackWindow
}

// Finalize runs any post-transaction state modifications (e.g. block rewards)
// and assembles the final block.
//
Expand Down
46 changes: 40 additions & 6 deletions consensus/istanbul/backend/pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package backend

import (
"errors"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -29,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/contract_comm/gold_token"
"github.com/ethereum/go-ethereum/contract_comm/validators"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
Expand Down Expand Up @@ -78,19 +81,50 @@ func (sb *Backend) distributeEpochPaymentsAndRewards(header *types.Header, state
}

func (sb *Backend) updateValidatorScores(header *types.Header, state *state.StateDB, valSet []istanbul.Validator) error {
for _, val := range valSet {
// TODO: Use actual uptime metric.
// 1.0 in fixidity
uptime := math.BigPow(10, 24)
sb.logger.Info("Updating validator score for address", "address", val.Address(), "uptime", uptime.String())
err := validators.UpdateValidatorScore(header, state, val.Address(), uptime)
// we need to use the previous
epoch := istanbul.GetEpochNumber(header.Number.Uint64(), sb.EpochSize())
log.Debug("uptime-trace: updateValidatorScores", "blocknum", header.Number.Uint64(), "epoch", epoch)
for i, val := range valSet {
uptime, err := sb.getUptime(i, epoch-1)
if err != nil {
return err
}
sb.logger.Info("Updating validator score for address", "index", i, "address", val.Address(), "uptime", uptime)
err = validators.UpdateValidatorScore(header, state, val.Address(), uptime)
if err != nil {
return err
}
}
return nil
}

func (sb *Backend) getUptime(validatorIndex int, epoch uint64) (*big.Int, error) {
// try to get a handle on the core.blockchain's database
// sb.db is a different database (defined in CreateConsensusEngine) :/
// is there a better way than this? don't think we want to pollute the interface
c := sb.chain.(*core.BlockChain)
db := c.GetDatabase()
uptimes := rawdb.ReadAccumulatedEpochUptime(db, epoch)
if uptimes == nil {
panic(fmt.Sprintf("could not read uptimes, i: %v", validatorIndex))
return nil, errors.New("Invalid accumulated uptime")
}

// skip the math if we've counted more signatures than necessary for that epoch
// when does this happen?
if uptimes[validatorIndex].Score >= sb.EpochSize()-2+1 { // sb.LookbackWindow()+1 {
// 1.0 in fixidity
return math.BigPow(10, 24), nil
}

// this will end up being between 0 and 1 but in fixidty
numerator := big.NewInt(0).Mul(big.NewInt(int64(uptimes[validatorIndex].Score)), math.BigPow(10, 24))
denominator := big.NewInt(int64(sb.EpochSize() - 2 + 1)) //- sb.LookbackWindow() + 1))
validatorUptime := big.NewInt(0).Div(numerator, denominator)

return validatorUptime, nil
}

func (sb *Backend) distributeEpochPayments(header *types.Header, state *state.StateDB, valSet []istanbul.Validator, maxPayment *big.Int) (*big.Int, error) {
totalEpochPayments := big.NewInt(0)
for _, val := range valSet {
Expand Down

0 comments on commit 1bb1ac0

Please sign in to comment.