tendermint/types/chain.go

134 lines
3.9 KiB
Go
Raw Normal View History

2016-01-15 16:55:24 -05:00
package types
import (
"fmt"
"sync"
2016-01-21 23:05:39 -05:00
"github.com/tendermint/netmon/Godeps/_workspace/src/github.com/rcrowley/go-metrics"
tmtypes "github.com/tendermint/netmon/Godeps/_workspace/src/github.com/tendermint/tendermint/types"
2016-01-15 16:55:24 -05:00
)
//------------------------------------------------
// blockchain types
2016-01-27 00:27:24 -05:00
//------------------------------------------------
2016-01-15 16:55:24 -05:00
2016-01-15 23:31:57 -05:00
// Known chain and validator set IDs (from which anything else can be found)
2016-01-27 00:27:24 -05:00
// Returned by the Status RPC
2016-01-15 23:31:57 -05:00
type ChainAndValidatorSetIDs struct {
ChainIDs []string `json:"chain_ids"`
ValidatorSetIDs []string `json:"validator_set_ids"`
}
2016-01-27 00:27:24 -05:00
//------------------------------------------------
// chain state
2016-01-15 23:31:57 -05:00
// Main chain state
2016-01-27 00:27:24 -05:00
// Returned over RPC; also used to manage state
2016-01-15 16:55:24 -05:00
type ChainState struct {
Config *BlockchainConfig `json:"config"`
Status *BlockchainStatus `json:"status"`
}
2016-01-27 00:27:24 -05:00
func (cs *ChainState) NewBlock(block *tmtypes.Block) {
cs.Status.NewBlock(block)
}
func (cs *ChainState) UpdateLatency(oldLatency, newLatency float64) {
cs.Status.UpdateLatency(oldLatency, newLatency)
}
2016-01-27 00:27:24 -05:00
//------------------------------------------------
// Blockchain Config: id, validator config
// Chain Config
2016-01-15 16:55:24 -05:00
type BlockchainConfig struct {
2016-01-27 00:27:24 -05:00
// should be fixed for life of chain
2016-01-15 23:31:57 -05:00
ID string `json:"id"`
2016-01-27 00:27:24 -05:00
ValSetID string `json:"val_set_id"` // NOTE: do we really commit to one val set per chain?
2016-01-15 16:55:24 -05:00
2016-01-27 00:27:24 -05:00
// handles live validator states (latency, last block, etc)
// and validator set changes
2016-01-15 23:31:57 -05:00
mtx sync.Mutex
Validators []*ValidatorState `json:"validators"` // TODO: this should be ValidatorConfig and the state in BlockchainStatus
2016-01-15 16:55:24 -05:00
valIDMap map[string]int // map IDs to indices
}
2016-01-27 00:27:24 -05:00
// So we can fetch validator by id rather than index
2016-01-15 16:55:24 -05:00
func (bc *BlockchainConfig) PopulateValIDMap() {
bc.mtx.Lock()
defer bc.mtx.Unlock()
bc.valIDMap = make(map[string]int)
for i, v := range bc.Validators {
bc.valIDMap[v.Config.Validator.ID] = i
2016-01-15 16:55:24 -05:00
}
}
func (bc *BlockchainConfig) GetValidatorByID(valID string) (*ValidatorState, error) {
2016-01-15 16:55:24 -05:00
bc.mtx.Lock()
defer bc.mtx.Unlock()
valIndex, ok := bc.valIDMap[valID]
if !ok {
return nil, fmt.Errorf("Unknown validator %s", valID)
}
return bc.Validators[valIndex], nil
}
2016-01-27 00:27:24 -05:00
//------------------------------------------------
// BlockchainStatus
// Basic blockchain metrics
type BlockchainStatus struct {
mtx sync.Mutex
// Blockchain Info
Height int `json:"height"`
BlockchainSize int64 `json:"blockchain_size"`
MeanBlockTime float64 `json:"mean_block_time" wire:"unsafe"`
TxThroughput float64 `json:"tx_throughput" wire:"unsafe"`
blockTimeMeter metrics.Meter
txThroughputMeter metrics.Meter
// Network Info
NumValidators int `json:"num_validators"`
ActiveValidators int `json:"active_validators"`
ActiveNodes int `json:"active_nodes"`
MeanLatency float64 `json:"mean_latency" wire:"unsafe"`
Uptime float64 `json:"uptime" wire:"unsafe"`
// What else can we get / do we want?
// TODO: charts for block time, latency (websockets/event-meter ?)
}
2016-01-15 16:55:24 -05:00
2016-01-27 00:27:24 -05:00
func NewBlockchainStatus() *BlockchainStatus {
return &BlockchainStatus{
blockTimeMeter: metrics.NewMeter(),
txThroughputMeter: metrics.NewMeter(),
2016-01-15 16:55:24 -05:00
}
2016-01-27 00:27:24 -05:00
}
2016-01-15 16:55:24 -05:00
2016-01-27 00:27:24 -05:00
func (s *BlockchainStatus) NewBlock(block *tmtypes.Block) {
s.mtx.Lock()
defer s.mtx.Unlock()
if block.Header.Height > s.Height {
s.Height = block.Header.Height
s.blockTimeMeter.Mark(1)
s.txThroughputMeter.Mark(int64(block.Header.NumTxs))
s.MeanBlockTime = 1 / s.blockTimeMeter.RateMean()
s.TxThroughput = s.txThroughputMeter.RateMean()
2016-01-15 16:55:24 -05:00
}
2016-01-27 00:27:24 -05:00
}
func (s *BlockchainStatus) UpdateLatency(oldLatency, newLatency float64) {
s.mtx.Lock()
defer s.mtx.Unlock()
// update latency for this validator and avg latency for chain
mean := s.MeanLatency * float64(s.NumValidators)
mean = (mean - oldLatency + newLatency) / float64(s.NumValidators)
s.MeanLatency = mean
2016-01-15 16:55:24 -05:00
2016-01-27 00:27:24 -05:00
// TODO: possibly update active nodes and uptime for chain
s.ActiveValidators = s.NumValidators // XXX
2016-01-15 16:55:24 -05:00
}