-
Notifications
You must be signed in to change notification settings - Fork 189
/
Copy pathblock.go
130 lines (114 loc) · 3.38 KB
/
block.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
package helper
import (
"math/rand"
"time"
"github.com/onflow/flow-go/consensus/hotstuff/model"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/utils/unittest"
)
func MakeBlock(options ...func(*model.Block)) *model.Block {
view := rand.Uint64()
block := model.Block{
View: view,
BlockID: unittest.IdentifierFixture(),
PayloadHash: unittest.IdentifierFixture(),
ProposerID: unittest.IdentifierFixture(),
Timestamp: time.Now().UTC(),
QC: MakeQC(WithQCView(view - 1)),
}
for _, option := range options {
option(&block)
}
return &block
}
func WithBlockView(view uint64) func(*model.Block) {
return func(block *model.Block) {
block.View = view
}
}
func WithBlockProposer(proposerID flow.Identifier) func(*model.Block) {
return func(block *model.Block) {
block.ProposerID = proposerID
}
}
func WithParentBlock(parent *model.Block) func(*model.Block) {
return func(block *model.Block) {
block.QC.BlockID = parent.BlockID
block.QC.View = parent.View
}
}
func WithParentSigners(signerIndices []byte) func(*model.Block) {
return func(block *model.Block) {
block.QC.SignerIndices = signerIndices
}
}
func WithBlockQC(qc *flow.QuorumCertificate) func(*model.Block) {
return func(block *model.Block) {
block.QC = qc
}
}
func MakeSignedProposal(options ...func(*model.SignedProposal)) *model.SignedProposal {
proposal := &model.SignedProposal{
Proposal: *MakeProposal(),
SigData: unittest.SignatureFixture(),
}
for _, option := range options {
option(proposal)
}
return proposal
}
func MakeProposal(options ...func(*model.Proposal)) *model.Proposal {
proposal := &model.Proposal{
Block: MakeBlock(),
LastViewTC: nil,
}
for _, option := range options {
option(proposal)
}
return proposal
}
func WithProposal(proposal *model.Proposal) func(*model.SignedProposal) {
return func(signedProposal *model.SignedProposal) {
signedProposal.Proposal = *proposal
}
}
func WithBlock(block *model.Block) func(*model.Proposal) {
return func(proposal *model.Proposal) {
proposal.Block = block
}
}
func WithSigData(sigData []byte) func(*model.SignedProposal) {
return func(proposal *model.SignedProposal) {
proposal.SigData = sigData
}
}
func WithLastViewTC(lastViewTC *flow.TimeoutCertificate) func(*model.Proposal) {
return func(proposal *model.Proposal) {
proposal.LastViewTC = lastViewTC
}
}
// SignedProposalToFlow turns a HotStuff block proposal into a flow block proposal.
//
// CAUTION: This function is only suitable for TESTING purposes ONLY.
// In the conversion from `flow.Header` to HotStuff's `model.Block` we lose information
// (e.g. `ChainID` and `Height` are not included in `model.Block`) and hence the conversion
// is *not reversible*. This is on purpose, because we wanted to only expose data to
// HotStuff that HotStuff really needs.
func SignedProposalToFlow(proposal *model.SignedProposal) *flow.Proposal {
block := proposal.Block
header := &flow.Header{
ParentID: block.QC.BlockID,
PayloadHash: block.PayloadHash,
Timestamp: block.Timestamp,
View: block.View,
ParentView: block.QC.View,
ParentVoterIndices: block.QC.SignerIndices,
ParentVoterSigData: block.QC.SigData,
ProposerID: block.ProposerID,
LastViewTC: proposal.LastViewTC,
}
return &flow.Proposal{
Header: header,
ProposerSigData: proposal.SigData,
}
}