mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-22 17:31:34 +00:00
signer interface for validators
This commit is contained in:
19
node/node.go
19
node/node.go
@ -41,7 +41,15 @@ type Node struct {
|
|||||||
privKey crypto.PrivKeyEd25519
|
privKey crypto.PrivKeyEd25519
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNode() *Node {
|
func NewNodeDefaultPrivVal() *Node {
|
||||||
|
// Get PrivValidator
|
||||||
|
privValidatorFile := config.GetString("priv_validator_file")
|
||||||
|
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
||||||
|
|
||||||
|
return NewNode(privValidator)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNode(privValidator *types.PrivValidator) *Node {
|
||||||
// Get BlockStore
|
// Get BlockStore
|
||||||
blockStoreDB := dbm.GetDB("blockstore")
|
blockStoreDB := dbm.GetDB("blockstore")
|
||||||
blockStore := bc.NewBlockStore(blockStoreDB)
|
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||||
@ -58,10 +66,6 @@ func NewNode() *Node {
|
|||||||
// add the chainid to the global config
|
// add the chainid to the global config
|
||||||
config.Set("chain_id", state.ChainID)
|
config.Set("chain_id", state.ChainID)
|
||||||
|
|
||||||
// Get PrivValidator
|
|
||||||
privValidatorFile := config.GetString("priv_validator_file")
|
|
||||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
|
||||||
|
|
||||||
// Generate node PrivKey
|
// Generate node PrivKey
|
||||||
privKey := crypto.GenPrivKeyEd25519()
|
privKey := crypto.GenPrivKeyEd25519()
|
||||||
|
|
||||||
@ -249,6 +253,9 @@ func makeNodeInfo(sw *p2p.Switch, privKey crypto.PrivKeyEd25519) *p2p.NodeInfo {
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Users wishing to use an external signer for their validators
|
||||||
|
// should fork tendermint/tendermint and implement RunNode to
|
||||||
|
// load their custom priv validator and call NewNode(privVal)
|
||||||
func RunNode() {
|
func RunNode() {
|
||||||
|
|
||||||
// Wait until the genesis doc becomes available
|
// Wait until the genesis doc becomes available
|
||||||
@ -274,7 +281,7 @@ func RunNode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create & start node
|
// Create & start node
|
||||||
n := NewNode()
|
n := NewNodeDefaultPrivVal()
|
||||||
l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp"))
|
l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp"))
|
||||||
n.AddListener(l)
|
n.AddListener(l)
|
||||||
err := n.Start()
|
err := n.Start()
|
||||||
|
@ -24,7 +24,7 @@ func TestNodeStartStop(t *testing.T) {
|
|||||||
time.Sleep(time.Second * 2)
|
time.Sleep(time.Second * 2)
|
||||||
|
|
||||||
// Create & start node
|
// Create & start node
|
||||||
n := NewNode()
|
n := NewNodeDefaultPrivVal()
|
||||||
l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp"))
|
l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp"))
|
||||||
n.AddListener(l)
|
n.AddListener(l)
|
||||||
n.Start()
|
n.Start()
|
||||||
|
@ -35,12 +35,15 @@ func voteToStep(vote *Vote) int8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PrivValidator struct {
|
type PrivValidator struct {
|
||||||
Address []byte `json:"address"`
|
Address []byte `json:"address"`
|
||||||
PubKey crypto.PubKeyEd25519 `json:"pub_key"`
|
PubKey crypto.PubKeyEd25519 `json:"pub_key"`
|
||||||
PrivKey crypto.PrivKeyEd25519 `json:"priv_key"`
|
LastHeight int `json:"last_height"`
|
||||||
LastHeight int `json:"last_height"`
|
LastRound int `json:"last_round"`
|
||||||
LastRound int `json:"last_round"`
|
LastStep int8 `json:"last_step"`
|
||||||
LastStep int8 `json:"last_step"`
|
|
||||||
|
// PrivKey should be empty if a Signer other than the default is being used.
|
||||||
|
PrivKey crypto.PrivKeyEd25519 `json:"priv_key"`
|
||||||
|
signer Signer
|
||||||
|
|
||||||
// For persistence.
|
// For persistence.
|
||||||
// Overloaded for testing.
|
// Overloaded for testing.
|
||||||
@ -48,6 +51,32 @@ type PrivValidator struct {
|
|||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: This is used to sign votes.
|
||||||
|
// It is the caller's duty to verify the msg before calling Sign,
|
||||||
|
// eg. to avoid double signing.
|
||||||
|
// Currently, the only callers are SignVote and SignProposal
|
||||||
|
type Signer interface {
|
||||||
|
Sign(msg []byte) crypto.SignatureEd25519
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements Signer
|
||||||
|
type DefaultSigner struct {
|
||||||
|
priv crypto.PrivKeyEd25519
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultSigner(priv crypto.PrivKeyEd25519) *DefaultSigner {
|
||||||
|
return &DefaultSigner{priv: priv}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements Signer
|
||||||
|
func (ds *DefaultSigner) Sign(msg []byte) crypto.SignatureEd25519 {
|
||||||
|
return ds.priv.Sign(msg).(crypto.SignatureEd25519)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (privVal *PrivValidator) SetSigner(s Signer) {
|
||||||
|
privVal.signer = s
|
||||||
|
}
|
||||||
|
|
||||||
// Generates a new validator with private key.
|
// Generates a new validator with private key.
|
||||||
func GenPrivValidator() *PrivValidator {
|
func GenPrivValidator() *PrivValidator {
|
||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := new([64]byte)
|
||||||
@ -63,6 +92,7 @@ func GenPrivValidator() *PrivValidator {
|
|||||||
LastRound: 0,
|
LastRound: 0,
|
||||||
LastStep: stepNone,
|
LastStep: stepNone,
|
||||||
filePath: "",
|
filePath: "",
|
||||||
|
signer: NewDefaultSigner(privKey),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +106,7 @@ func LoadPrivValidator(filePath string) *PrivValidator {
|
|||||||
Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
|
Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
|
||||||
}
|
}
|
||||||
privVal.filePath = filePath
|
privVal.filePath = filePath
|
||||||
|
privVal.signer = NewDefaultSigner(privVal.PrivKey)
|
||||||
return privVal
|
return privVal
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,14 +176,10 @@ func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error {
|
|||||||
privVal.save()
|
privVal.save()
|
||||||
|
|
||||||
// Sign
|
// Sign
|
||||||
privVal.SignVoteUnsafe(chainID, vote)
|
vote.Signature = privVal.signer.Sign(SignBytes(chainID, vote))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *Vote) {
|
|
||||||
vote.Signature = privVal.PrivKey.Sign(SignBytes(chainID, vote)).(crypto.SignatureEd25519)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error {
|
func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error {
|
||||||
privVal.mtx.Lock()
|
privVal.mtx.Lock()
|
||||||
defer privVal.mtx.Unlock()
|
defer privVal.mtx.Unlock()
|
||||||
@ -167,7 +194,7 @@ func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) e
|
|||||||
privVal.save()
|
privVal.save()
|
||||||
|
|
||||||
// Sign
|
// Sign
|
||||||
proposal.Signature = privVal.PrivKey.Sign(SignBytes(chainID, proposal)).(crypto.SignatureEd25519)
|
proposal.Signature = privVal.signer.Sign(SignBytes(chainID, proposal))
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round))
|
return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round))
|
||||||
|
@ -60,7 +60,7 @@ func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) {
|
func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) {
|
||||||
privVal.SignVoteUnsafe(config.GetString("chain_id"), vote)
|
vote.Signature = privVal.signer.Sign(SignBytes(config.GetString("chain_id"), vote))
|
||||||
added, _, err := voteSet.AddByAddress(privVal.Address, vote)
|
added, _, err := voteSet.AddByAddress(privVal.Address, vote)
|
||||||
return added, err
|
return added, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user