Browse Source

node: allow registration of custom reactors while creating node (#3771)

* change invocation of NewNode across

* custom reactor name are prefixed with CUSTOM_

* upgate changelog pending

* improve comments

* node: refactor NewNode to use functional options
pull/3775/head
Anton Kaliaev 6 years ago
committed by GitHub
parent
commit
f76684a05c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 2 deletions
  1. +4
    -0
      CHANGELOG_PENDING.md
  2. +24
    -1
      node/node.go
  3. +33
    -1
      node/node_test.go
  4. +23
    -0
      p2p/mock/reactor.go

+ 4
- 0
CHANGELOG_PENDING.md View File

@ -26,6 +26,10 @@ program](https://hackerone.com/tendermint).
* P2P Protocol
### FEATURES:
- [node] Refactor `NewNode` to use functional options to make it more flexible
and extensible in the future.
- [node] [\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass
custom reactors to run inside Tendermint node (@ParthDesai)
### IMPROVEMENTS:
- [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73)


+ 24
- 1
node/node.go View File

@ -47,6 +47,10 @@ import (
"github.com/tendermint/tendermint/version"
)
// CustomReactorNamePrefix is a prefix for all custom reactors to prevent
// clashes with built-in reactors.
const CustomReactorNamePrefix = "CUSTOM_"
//------------------------------------------------------------------------------
// DBContext specifies config information for loading a new DB.
@ -136,6 +140,18 @@ func DefaultMetricsProvider(config *cfg.InstrumentationConfig) MetricsProvider {
}
}
// Option sets a parameter for the node.
type Option func(*Node)
// CustomReactors allows you to add custom reactors to the node's Switch.
func CustomReactors(reactors map[string]p2p.Reactor) Option {
return func(n *Node) {
for name, reactor := range reactors {
n.sw.AddReactor(CustomReactorNamePrefix+name, reactor)
}
}
}
//------------------------------------------------------------------------------
// Node is the highest level interface to a full Tendermint node.
@ -433,6 +449,7 @@ func createSwitch(config *cfg.Config,
sw.AddReactor("BLOCKCHAIN", bcReactor)
sw.AddReactor("CONSENSUS", consensusReactor)
sw.AddReactor("EVIDENCE", evidenceReactor)
sw.SetNodeInfo(nodeInfo)
sw.SetNodeKey(nodeKey)
@ -495,7 +512,8 @@ func NewNode(config *cfg.Config,
genesisDocProvider GenesisDocProvider,
dbProvider DBProvider,
metricsProvider MetricsProvider,
logger log.Logger) (*Node, error) {
logger log.Logger,
options ...Option) (*Node, error) {
blockStore, stateDB, err := initDBs(config, dbProvider)
if err != nil {
@ -661,6 +679,11 @@ func NewNode(config *cfg.Config,
eventBus: eventBus,
}
node.BaseService = *cmn.NewBaseService(logger, "Node", node)
for _, option := range options {
option(node)
}
return node, nil
}


+ 33
- 1
node/node_test.go View File

@ -21,6 +21,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
mempl "github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/p2p"
p2pmock "github.com/tendermint/tendermint/p2p/mock"
"github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state"
@ -100,7 +101,10 @@ func TestNodeDelayedStart(t *testing.T) {
n.GenesisDoc().GenesisTime = now.Add(2 * time.Second)
require.NoError(t, err)
n.Start()
err = n.Start()
require.NoError(t, err)
defer n.Stop()
startTime := tmtime.Now()
assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime))
}
@ -279,6 +283,34 @@ func TestCreateProposalBlock(t *testing.T) {
assert.NoError(t, err)
}
func TestNodeNewNodeCustomReactors(t *testing.T) {
config := cfg.ResetTestRoot("node_new_node_custom_reactors_test")
defer os.RemoveAll(config.RootDir)
cr := p2pmock.NewReactor()
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
require.NoError(t, err)
n, err := NewNode(config,
privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()),
nodeKey,
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
DefaultGenesisDocProviderFunc(config),
DefaultDBProvider,
DefaultMetricsProvider(config.Instrumentation),
log.TestingLogger(),
CustomReactors(map[string]p2p.Reactor{"FOO": cr}),
)
require.NoError(t, err)
err = n.Start()
require.NoError(t, err)
defer n.Stop()
assert.True(t, cr.IsRunning())
}
func state(nVals int, height int64) (sm.State, dbm.DB) {
vals := make([]types.GenesisValidator, nVals)
for i := 0; i < nVals; i++ {


+ 23
- 0
p2p/mock/reactor.go View File

@ -0,0 +1,23 @@
package mock
import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/p2p/conn"
)
type Reactor struct {
p2p.BaseReactor
}
func NewReactor() *Reactor {
r := &Reactor{}
r.BaseReactor = *p2p.NewBaseReactor("Reactor", r)
r.SetLogger(log.TestingLogger())
return r
}
func (r *Reactor) GetChannels() []*conn.ChannelDescriptor { return []*conn.ChannelDescriptor{} }
func (r *Reactor) AddPeer(peer p2p.Peer) {}
func (r *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {}
func (r *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {}

Loading…
Cancel
Save