Skip to content
Snippets Groups Projects
Commit 31a11627 authored by Ethan Buchman's avatar Ethan Buchman
Browse files

add genesis hash to p2p handshake. closes #56

parent 86cbb6be
No related branches found
No related tags found
No related merge requests found
...@@ -152,7 +152,8 @@ func NewNode(privValidator *types.PrivValidator) *Node { ...@@ -152,7 +152,8 @@ func NewNode(privValidator *types.PrivValidator) *Node {
// Call Start() after adding the listeners. // Call Start() after adding the listeners.
func (n *Node) Start() error { func (n *Node) Start() error {
n.book.Start() n.book.Start()
n.sw.SetNodeInfo(makeNodeInfo(n.sw, n.privKey)) genState := sm.MakeGenesisState(dbm.NewMemDB(), n.genDoc)
n.sw.SetNodeInfo(makeNodeInfo(n.sw, n.privKey, genState.Hash()))
n.sw.SetNodePrivKey(n.privKey) n.sw.SetNodePrivKey(n.privKey)
_, err := n.sw.Start() _, err := n.sw.Start()
return err return err
...@@ -247,12 +248,13 @@ func (n *Node) EventSwitch() *events.EventSwitch { ...@@ -247,12 +248,13 @@ func (n *Node) EventSwitch() *events.EventSwitch {
return n.evsw return n.evsw
} }
func makeNodeInfo(sw *p2p.Switch, privKey acm.PrivKeyEd25519) *types.NodeInfo { func makeNodeInfo(sw *p2p.Switch, privKey acm.PrivKeyEd25519, genesisRoot []byte) *types.NodeInfo {
nodeInfo := &types.NodeInfo{ nodeInfo := &types.NodeInfo{
PubKey: privKey.PubKey().(acm.PubKeyEd25519), PubKey: privKey.PubKey().(acm.PubKeyEd25519),
Moniker: config.GetString("moniker"), Moniker: config.GetString("moniker"),
ChainID: config.GetString("chain_id"), ChainID: config.GetString("chain_id"),
Genesis: genesisRoot,
Version: types.Versions{ Version: types.Versions{
Tendermint: Version, Tendermint: Version,
P2P: p2p.Version, P2P: p2p.Version,
......
package node package node
import ( import (
"strconv"
"strings"
"testing" "testing"
"time" "time"
_ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test"
dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/db"
"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p"
sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state"
stypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state/types"
"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types"
) )
func TestNodeStartStop(t *testing.T) { func TestNodeStartStop(t *testing.T) {
...@@ -28,3 +34,46 @@ func TestNodeStartStop(t *testing.T) { ...@@ -28,3 +34,46 @@ func TestNodeStartStop(t *testing.T) {
t.Fatal("timed out waiting for shutdown") t.Fatal("timed out waiting for shutdown")
} }
} }
func TestCompatibleNodeInfo(t *testing.T) {
sw := p2p.NewSwitch()
priv1, priv2 := types.GenPrivValidator(), types.GenPrivValidator()
genDoc1, _, _ := stypes.RandGenesisDoc(5, true, 100, 4, true, 1000)
genState1 := sm.MakeGenesisState(dbm.NewMemDB(), genDoc1)
genDoc2, _, _ := stypes.RandGenesisDoc(5, true, 100, 4, true, 1000)
genState2 := sm.MakeGenesisState(dbm.NewMemDB(), genDoc2)
// incompatible genesis states
n1 := makeNodeInfo(sw, priv1.PrivKey, genState1.Hash())
n2 := makeNodeInfo(sw, priv2.PrivKey, genState2.Hash())
if err := n1.CompatibleWith(n2); err == nil {
t.Fatalf("Expected nodes to be incompatible due to genesis state")
}
// incompatible chain ids
copy(n2.Genesis, n1.Genesis)
n2.ChainID = "incryptowetrust"
if err := n1.CompatibleWith(n2); err == nil {
t.Fatalf("Expected nodes to be incompatible due to chain ID")
}
// incompatible versions
n2.ChainID = n1.ChainID
v := n1.Version.Tendermint
spl := strings.Split(v, ".")
n, err := strconv.Atoi(spl[0])
if err != nil {
t.Fatalf(err.Error())
}
spl[0] = strconv.Itoa(n + 1)
n2.Version.Tendermint = strings.Join(spl, ".")
if err := n1.CompatibleWith(n2); err == nil {
t.Fatalf("Expected nodes to be incompatible due to major version")
}
// compatible
n2.Version.Tendermint = n1.Version.Tendermint
if err := n1.CompatibleWith(n2); err != nil {
t.Fatalf("Expected nodes to be compatible")
}
}
...@@ -220,7 +220,7 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er ...@@ -220,7 +220,7 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er
sconn.Close() sconn.Close()
return nil, fmt.Errorf("Ignoring connection from self") return nil, fmt.Errorf("Ignoring connection from self")
} }
// Check version, chain id // Check version, chain id, genesis hash
if err := sw.nodeInfo.CompatibleWith(peerNodeInfo); err != nil { if err := sw.nodeInfo.CompatibleWith(peerNodeInfo); err != nil {
sconn.Close() sconn.Close()
return nil, err return nil, err
......
package types package types
import ( import (
"bytes"
"fmt" "fmt"
acm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/account"
"strings" "strings"
acm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/account"
) )
type NodeInfo struct { type NodeInfo struct {
PubKey acm.PubKeyEd25519 `json:"pub_key"` PubKey acm.PubKeyEd25519 `json:"pub_key"`
Moniker string `json:"moniker"` Moniker string `json:"moniker"`
ChainID string `json:"chain_id"` ChainID string `json:"chain_id"`
Genesis []byte `json:"genesis"`
Host string `json:"host"` Host string `json:"host"`
P2PPort uint16 `json:"p2p_port"` P2PPort uint16 `json:"p2p_port"`
RPCPort uint16 `json:"rpc_port"` RPCPort uint16 `json:"rpc_port"`
...@@ -25,7 +28,7 @@ type Versions struct { ...@@ -25,7 +28,7 @@ type Versions struct {
Wire string `json:"wire"` Wire string `json:"wire"`
} }
// CONTRACT: two nodes with the same Tendermint major and minor version and with the same ChainID are compatible // CONTRACT: two nodes with the same Tendermint major and minor version and with the same ChainID and Genesis are compatible
func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error { func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error {
iM, im, _, ie := splitVersion(ni.Version.Tendermint) iM, im, _, ie := splitVersion(ni.Version.Tendermint)
oM, om, _, oe := splitVersion(no.Version.Tendermint) oM, om, _, oe := splitVersion(no.Version.Tendermint)
...@@ -55,6 +58,11 @@ func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error { ...@@ -55,6 +58,11 @@ func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error {
return fmt.Errorf("Peer is on a different chain_id. Got %v, expected %v", no.ChainID, ni.ChainID) return fmt.Errorf("Peer is on a different chain_id. Got %v, expected %v", no.ChainID, ni.ChainID)
} }
// nodes must share a common genesis root
if !bytes.Equal(ni.Genesis, no.Genesis) {
return fmt.Errorf("Peer has a different genesis root. Got %v, expected %v", no.Genesis, ni.Genesis)
}
return nil return nil
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment