You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
3.6 KiB

9 years ago
  1. package handlers
  2. import (
  3. "fmt"
  4. "sort"
  5. "sync"
  6. "github.com/tendermint/go-event-meter"
  7. "github.com/tendermint/go-wire"
  8. "github.com/tendermint/netmon/types"
  9. )
  10. type NetMonResultInterface interface{}
  11. type NetMonResult struct {
  12. Result NetMonResultInterface
  13. }
  14. // for wire.readReflect
  15. var _ = wire.RegisterInterface(
  16. struct{ NetMonResultInterface }{},
  17. wire.ConcreteType{&types.ChainAndValidatorIDs{}, 0x01},
  18. wire.ConcreteType{&types.ChainStatus{}, 0x02},
  19. wire.ConcreteType{&types.Validator{}, 0x03},
  20. wire.ConcreteType{&eventmeter.EventMetric{}, 0x04},
  21. )
  22. //---------------------------------------------
  23. // global state and backend functions
  24. type TendermintNetwork struct {
  25. mtx sync.Mutex
  26. Chains map[string]*types.ChainStatus `json:"blockchains"`
  27. ValSets map[string]*types.ValidatorSet `json:"validator_sets"`
  28. }
  29. // TODO: populate validator sets
  30. func NewTendermintNetwork(chains ...*types.ChainStatus) *TendermintNetwork {
  31. network := &TendermintNetwork{
  32. Chains: make(map[string]*types.ChainStatus),
  33. ValSets: make(map[string]*types.ValidatorSet),
  34. }
  35. for _, chain := range chains {
  36. network.Chains[chain.Config.ID] = chain
  37. }
  38. return network
  39. }
  40. //------------
  41. // RPC funcs
  42. func (tn *TendermintNetwork) Status() (*types.ChainAndValidatorIDs, error) {
  43. tn.mtx.Lock()
  44. defer tn.mtx.Unlock()
  45. chains := make([]string, len(tn.Chains))
  46. valSets := make([]string, len(tn.ValSets))
  47. i := 0
  48. for chain, _ := range tn.Chains {
  49. chains[i] = chain
  50. i += 1
  51. }
  52. i = 0
  53. for valset, _ := range tn.ValSets {
  54. valSets[i] = valset
  55. i += 1
  56. }
  57. sort.StringSlice(chains).Sort()
  58. sort.StringSlice(valSets).Sort()
  59. return &types.ChainAndValidatorIDs{
  60. ChainIDs: chains,
  61. ValidatorSetIDs: valSets,
  62. }, nil
  63. }
  64. func (tn *TendermintNetwork) GetChain(chainID string) (*types.ChainStatus, error) {
  65. tn.mtx.Lock()
  66. defer tn.mtx.Unlock()
  67. chain, ok := tn.Chains[chainID]
  68. if !ok {
  69. return nil, fmt.Errorf("Unknown chain %s", chainID)
  70. }
  71. return chain, nil
  72. }
  73. func (tn *TendermintNetwork) GetValidatorSet(valSetID string) (*types.ValidatorSet, error) {
  74. tn.mtx.Lock()
  75. defer tn.mtx.Unlock()
  76. valSet, ok := tn.ValSets[valSetID]
  77. if !ok {
  78. return nil, fmt.Errorf("Unknown validator set %s", valSetID)
  79. }
  80. return valSet, nil
  81. }
  82. func (tn *TendermintNetwork) GetValidator(valSetID, valID string) (*types.Validator, error) {
  83. tn.mtx.Lock()
  84. defer tn.mtx.Unlock()
  85. valSet, ok := tn.ValSets[valSetID]
  86. if !ok {
  87. return nil, fmt.Errorf("Unknown validator set %s", valSetID)
  88. }
  89. val, err := valSet.Validator(valID)
  90. if err != nil {
  91. return nil, err
  92. }
  93. return val, nil
  94. }
  95. func (tn *TendermintNetwork) StartMeter(chainID, valID, eventID string) error {
  96. tn.mtx.Lock()
  97. defer tn.mtx.Unlock()
  98. val, err := tn.getChainVal(chainID, valID)
  99. if err != nil {
  100. return err
  101. }
  102. return val.EventMeter().Subscribe(eventID, nil)
  103. }
  104. func (tn *TendermintNetwork) StopMeter(chainID, valID, eventID string) error {
  105. tn.mtx.Lock()
  106. defer tn.mtx.Unlock()
  107. val, err := tn.getChainVal(chainID, valID)
  108. if err != nil {
  109. return err
  110. }
  111. return val.EventMeter().Unsubscribe(eventID)
  112. }
  113. func (tn *TendermintNetwork) GetMeter(chainID, valID, eventID string) (*eventmeter.EventMetric, error) {
  114. tn.mtx.Lock()
  115. defer tn.mtx.Unlock()
  116. val, err := tn.getChainVal(chainID, valID)
  117. if err != nil {
  118. return nil, err
  119. }
  120. return val.EventMeter().GetMetric(eventID)
  121. }
  122. func (tn *TendermintNetwork) getChainVal(chainID, valID string) (*types.ChainValidator, error) {
  123. chain, ok := tn.Chains[chainID]
  124. if !ok {
  125. return nil, fmt.Errorf("Unknown chain %s", chainID)
  126. }
  127. val, err := chain.Config.GetValidatorByID(valID)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return val, nil
  132. }