tendermint/handlers/callbacks.go

79 lines
2.4 KiB
Go
Raw Normal View History

2016-01-15 23:31:57 -05:00
package handlers
import (
2016-02-02 20:21:06 -05:00
"time"
2016-02-02 13:10:43 -05:00
"github.com/tendermint/go-event-meter"
"github.com/tendermint/go-events"
2016-01-15 23:31:57 -05:00
2016-01-27 00:27:24 -05:00
"github.com/tendermint/netmon/types"
2016-02-02 13:10:43 -05:00
tmtypes "github.com/tendermint/tendermint/types"
2016-01-15 23:31:57 -05:00
)
2016-01-27 00:27:24 -05:00
/*
Each chain-validator gets an eventmeter which maintains the websocket
Certain pre-defined events may update the netmon state: latency pongs, new blocks
2016-02-02 20:21:06 -05:00
All callbacks are called in a go-routine by the event-meter
2016-01-27 00:27:24 -05:00
TODO: config changes for new validators and changing ip/port
*/
2016-02-02 20:21:06 -05:00
func (tn *TendermintNetwork) registerCallbacks(chainState *types.ChainState, v *types.ValidatorState) error {
v.EventMeter().RegisterLatencyCallback(tn.latencyCallback(chainState, v))
v.EventMeter().RegisterDisconnectCallback(tn.disconnectCallback(chainState, v))
2016-04-20 14:52:11 -04:00
return v.EventMeter().Subscribe(tmtypes.EventStringNewBlockHeader(), tn.newBlockCallback(chainState, v))
2016-02-02 20:21:06 -05:00
}
2016-01-15 23:31:57 -05:00
// implements eventmeter.EventCallbackFunc
2016-01-27 00:27:24 -05:00
// updates validator and possibly chain with new block
func (tn *TendermintNetwork) newBlockCallback(chainState *types.ChainState, val *types.ValidatorState) eventmeter.EventCallbackFunc {
2016-01-15 23:31:57 -05:00
return func(metric *eventmeter.EventMetric, data events.EventData) {
2016-04-20 14:52:11 -04:00
block := data.(tmtypes.EventDataNewBlockHeader).Header
2016-01-15 23:31:57 -05:00
2016-01-27 00:27:24 -05:00
// these functions are thread safe
// we should run them concurrently
2016-01-15 23:31:57 -05:00
// update height for validator
2016-01-27 00:27:24 -05:00
val.NewBlock(block)
2016-01-15 23:31:57 -05:00
// possibly update height and mean block time for chain
2016-01-27 00:27:24 -05:00
chainState.NewBlock(block)
2016-01-15 23:31:57 -05:00
}
}
// implements eventmeter.EventLatencyFunc
2016-01-27 00:27:24 -05:00
func (tn *TendermintNetwork) latencyCallback(chain *types.ChainState, val *types.ValidatorState) eventmeter.LatencyCallbackFunc {
2016-01-15 23:31:57 -05:00
return func(latency float64) {
2016-01-27 00:40:07 -05:00
latency = latency / 1000000.0 // ns to ms
2016-01-27 00:27:24 -05:00
oldLatency := val.UpdateLatency(latency)
chain.UpdateLatency(oldLatency, latency)
2016-01-15 23:31:57 -05:00
}
}
2016-02-02 13:10:43 -05:00
// implements eventmeter.DisconnectCallbackFunc
func (tn *TendermintNetwork) disconnectCallback(chain *types.ChainState, val *types.ValidatorState) eventmeter.DisconnectCallbackFunc {
return func() {
// Validator is down!
chain.SetOnline(val, false)
2016-02-02 20:21:06 -05:00
// reconnect
// TODO: stop trying eventually ...
for {
time.Sleep(time.Second)
if err := val.Start(); err != nil {
log.Debug("Can't connect to validator", "valID", val.Config.Validator.ID)
} else {
// register callbacks for the validator
tn.registerCallbacks(chain, val)
chain.SetOnline(val, true)
// TODO: authenticate pubkey
return
}
}
2016-02-02 13:10:43 -05:00
}
}