mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-12 23:07:11 +00:00
120 lines
2.8 KiB
Go
120 lines
2.8 KiB
Go
|
package types
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/tendermint/go-event-meter"
|
||
|
"github.com/tendermint/go-crypto"
|
||
|
)
|
||
|
|
||
|
//---------------------------------------------
|
||
|
// core types
|
||
|
|
||
|
// Known chain and validator set IDs (from which anything else can be found)
|
||
|
type ChainAndValidatorIDs struct {
|
||
|
ChainIDs []string `json:"chain_ids"`
|
||
|
ValidatorSetIDs []string `json:"validator_set_ids"`
|
||
|
}
|
||
|
|
||
|
// state of a chain
|
||
|
type ChainStatus struct {
|
||
|
Config *BlockchainConfig `json:"config"`
|
||
|
Status *BlockchainStatus `json:"status"`
|
||
|
}
|
||
|
|
||
|
// basic chain config
|
||
|
// threadsafe
|
||
|
type BlockchainConfig struct {
|
||
|
mtx sync.Mutex
|
||
|
|
||
|
ID string `json:"id"`
|
||
|
ValSetID string `json:"val_set_id"`
|
||
|
Validators []*ChainValidator `json:"validators"`
|
||
|
valIDMap map[string]int // map IDs to indices
|
||
|
}
|
||
|
|
||
|
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.ID] = i
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bc *BlockchainConfig) GetValidatorByID(valID string) (*ChainValidator, error) {
|
||
|
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
|
||
|
}
|
||
|
|
||
|
// basic chain status/metrics
|
||
|
// threadsafe
|
||
|
type BlockchainStatus struct {
|
||
|
mtx sync.Mutex
|
||
|
|
||
|
Height int `json:"height"`
|
||
|
MeanBlockTime float64 `json:"mean_block_time"`
|
||
|
TxThroughput float64 `json:"tx_throughput"`
|
||
|
|
||
|
BlockchainSize int64 `json:"blockchain_size"` // how might we get StateSize ?
|
||
|
}
|
||
|
|
||
|
// validator on a chain
|
||
|
type ChainValidator struct {
|
||
|
*Validator
|
||
|
Addr string `json:"addr"` // do we want multiple addrs?
|
||
|
Index int `json:"index"`
|
||
|
|
||
|
em *eventmeter.EventMeter // holds a ws connection to the val
|
||
|
Latency float64 `json:"latency,omitempty"`
|
||
|
}
|
||
|
|
||
|
func (cv *ChainValidator) NewEventMeter() error {
|
||
|
em := eventmeter.NewEventMeter(fmt.Sprintf("ws://%s/websocket", cv.Addr))
|
||
|
if err := em.Start(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
cv.em = em
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (cv *ChainValidator) EventMeter() *eventmeter.EventMeter {
|
||
|
return cv.em
|
||
|
}
|
||
|
|
||
|
// validator set (independent of chains)
|
||
|
type ValidatorSet struct {
|
||
|
Validators []*Validator `json:"validators"`
|
||
|
}
|
||
|
|
||
|
func (vs *ValidatorSet) Validator(valID string) (*Validator, error) {
|
||
|
for _, v := range vs.Validators {
|
||
|
if v.ID == valID {
|
||
|
return v, nil
|
||
|
}
|
||
|
}
|
||
|
return nil, fmt.Errorf("Unknwon validator %s", valID)
|
||
|
}
|
||
|
|
||
|
// validator (independent of chain)
|
||
|
type Validator struct {
|
||
|
ID string `json:"id"`
|
||
|
PubKey crypto.PubKey `json:"pub_key,omitempty"`
|
||
|
Chains []*ChainStatus `json:"chains,omitempty"`
|
||
|
}
|
||
|
|
||
|
func (v *Validator) Chain(chainID string) (*ChainStatus, error) {
|
||
|
for _, c := range v.Chains {
|
||
|
if c.Config.ID == chainID {
|
||
|
return c, nil
|
||
|
}
|
||
|
}
|
||
|
return nil, fmt.Errorf("Unknwon chain %s", chainID)
|
||
|
}
|