This repository has been archived by the owner on Oct 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
133 lines (110 loc) · 3.36 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package janus
import (
"fmt"
"github.com/tendermint/tendermint/libs/service"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"time"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
"errors"
"github.com/tendermint/tendermint/types"
)
var (
// ErrSignatureRejected indicates that the signature is already locked or locking failed
ErrSignatureRejected = errors.New("signature rejected")
)
// EtcdSigningWrapper implements PrivValidator by wrapping the etcd locking around a PrivValidator
type EtcdSigningWrapper struct {
service.BaseService
privVal types.PrivValidator
locker *Locker
timeout time.Duration
validatorName string
lockerEndpoints []string
}
// NewEtcdSigningWrapper returns an instance of EtcdSigningWrapper.
func NewEtcdSigningWrapper(
logger log.Logger,
privVal types.PrivValidator,
timeout time.Duration,
validatorName string,
lockerEndpoints []string,
) *EtcdSigningWrapper {
rs := &EtcdSigningWrapper{
privVal: privVal,
timeout: timeout,
validatorName: validatorName,
lockerEndpoints: lockerEndpoints,
}
rs.BaseService = *service.NewBaseService(logger, "EtcdSigningWrapper", rs)
return rs
}
// OnStart implements cmn.Service.
func (es *EtcdSigningWrapper) OnStart() error {
// Start etcd ?
locker, err := NewLocker(es.lockerEndpoints, es.timeout)
if err != nil {
return err
}
es.locker = locker
return nil
}
// OnStop implements cmn.Service.
func (es *EtcdSigningWrapper) OnStop() {
es.locker.Disconnect()
es.locker = nil
}
// GetPubKey returns the public key of the validator.
// Implements PrivValidator.
func (es *EtcdSigningWrapper) GetPubKey() (crypto.PubKey, error) {
return es.privVal.GetPubKey()
}
// SignVote signs a canonical representation of the vote, along with the
// chainID. Implements PrivValidator.
func (es *EtcdSigningWrapper) SignVote(chainID string, vote *tmproto.Vote) error {
if err := es.privVal.SignVote(chainID, vote); err != nil {
return fmt.Errorf("error signing vote: %v", err)
}
var voteType string
switch vote.Type {
case tmproto.PrevoteType:
voteType = "prevote"
case tmproto.PrecommitType:
voteType = "precommit"
default:
return errors.New("invalid vote type")
}
var err error
lockAcquired := false
if vote.Type == tmproto.PrevoteType {
lockAcquired, err = es.locker.TryLockSetHash(es.validatorName, fmt.Sprintf("vote_%s", voteType), vote.Height, int(vote.Round), vote.BlockID.String())
} else {
lockAcquired, err = es.locker.TryLockCheckHash(es.validatorName, fmt.Sprintf("vote_%s", voteType), vote.Height, int(vote.Round), vote.BlockID.String())
}
if err != nil {
vote.Signature = nil
return err
}
if !lockAcquired {
vote.Signature = nil
return ErrSignatureRejected
}
return nil
}
// SignProposal signs a canonical representation of the proposal, along with
// the chainID. Implements PrivValidator.
func (es *EtcdSigningWrapper) SignProposal(chainID string, proposal *tmproto.Proposal) error {
if err := es.privVal.SignProposal(chainID, proposal); err != nil {
return fmt.Errorf("error signing proposal: %v", err)
}
lockAcquired, err := es.locker.TryLock(es.validatorName, "proposal", proposal.Height, int(proposal.Round))
if err != nil {
proposal.Signature = nil
return err
}
if !lockAcquired {
proposal.Signature = nil
return ErrSignatureRejected
}
return nil
}