-
Notifications
You must be signed in to change notification settings - Fork 8.8k
/
signer.go
82 lines (68 loc) · 2.13 KB
/
signer.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
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package smartbft
import (
"github.com/hyperledger-labs/SmartBFT/pkg/types"
cb "github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/common/crypto"
"github.com/hyperledger/fabric/internal/pkg/identity"
"github.com/hyperledger/fabric/protoutil"
)
//go:generate mockery --dir . --name SignerSerializer --case underscore --with-expecter=true --output mocks
// SignerSerializer signs messages and serializes identities
type SignerSerializer interface {
identity.SignerSerializer
}
// Signer implementation
type Signer struct {
ID uint64
SignerSerializer SignerSerializer
Logger Logger
LastConfigBlockNum func(*cb.Block) uint64
}
// Sign signs the message
func (s *Signer) Sign(msg []byte) []byte {
signature, err := s.SignerSerializer.Sign(msg)
if err != nil {
s.Logger.Panicf("Failed signing message: %v", err)
}
return signature
}
// SignProposal signs the proposal
func (s *Signer) SignProposal(proposal types.Proposal, _ []byte) *types.Signature {
block, err := ProposalToBlock(proposal)
if err != nil {
s.Logger.Panicf("Tried to sign bad proposal: %v", err)
}
nonce := randomNonceOrPanic()
sig := Signature{
BlockHeader: protoutil.BlockHeaderBytes(block.Header),
IdentifierHeader: protoutil.MarshalOrPanic(s.newIdentifierHeaderOrPanic(nonce)),
OrdererBlockMetadata: protoutil.MarshalOrPanic(&cb.OrdererBlockMetadata{
LastConfig: &cb.LastConfig{Index: s.LastConfigBlockNum(block)},
ConsenterMetadata: proposal.Metadata,
}),
}
signature := protoutil.SignOrPanic(s.SignerSerializer, sig.AsBytes())
return &types.Signature{
ID: s.ID,
Value: signature,
Msg: sig.Marshal(),
}
}
// newIdentifierHeaderOrPanic creates an IdentifierHeader with the signer's identifier and a valid nonce
func (s *Signer) newIdentifierHeaderOrPanic(nonce []byte) *cb.IdentifierHeader {
return &cb.IdentifierHeader{
Identifier: uint32(s.ID),
Nonce: nonce,
}
}
func randomNonceOrPanic() []byte {
nonce, err := crypto.GetRandomNonce()
if err != nil {
panic(err)
}
return nonce
}