mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-12 23:07:11 +00:00
140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
package types
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"sync"
|
|
|
|
"github.com/tendermint/go-crypto"
|
|
"github.com/tendermint/go-event-meter"
|
|
"github.com/tendermint/go-events"
|
|
"github.com/tendermint/go-wire"
|
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
|
)
|
|
|
|
//---------------------------------------------
|
|
// 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" wire:"unsafe"`
|
|
TxThroughput float64 `json:"tx_throughput" wire:"unsafe"`
|
|
|
|
BlockchainSize int64 `json:"blockchain_size"` // how might we get StateSize ?
|
|
}
|
|
|
|
// validator on a chain
|
|
type ChainValidator struct {
|
|
*Validator `json:"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" wire:"unsafe"`
|
|
}
|
|
|
|
func unmarshalEvent(b json.RawMessage) (string, events.EventData, error) {
|
|
var err error
|
|
result := new(ctypes.TMResult)
|
|
wire.ReadJSONPtr(result, b, &err)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
event, ok := (*result).(*ctypes.ResultEvent)
|
|
if !ok {
|
|
return "", nil, fmt.Errorf("Result is not type *ctypes.ResultEvent. Got %v", reflect.TypeOf(*result))
|
|
}
|
|
return event.Name, event.Data, nil
|
|
|
|
}
|
|
|
|
func (cv *ChainValidator) NewEventMeter() error {
|
|
em := eventmeter.NewEventMeter(fmt.Sprintf("ws://%s/websocket", cv.Addr), unmarshalEvent)
|
|
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)
|
|
}
|