Skip to content

Commit cff44df

Browse files
committed
[Malleability] Header: add UnsignedHeader and malleability test
Change the Header to use an embedded UnsignedHeader struct, representing the main data of the header (all except the Proposer signature data). UnsignedHeader is verified to not be malleable, but Header.ID() is not yet updated to take ProposerSigData into account, meaning Header is still malleable. Changing Header's ID (also used as Block ID) causes many tests to break/fail, which will need more detailed investigation and work.
1 parent 6e1d198 commit cff44df

File tree

32 files changed

+232
-197
lines changed

32 files changed

+232
-197
lines changed

admin/commands/execution/stop_at_height_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func TestCommandsSetsValues(t *testing.T) {
9999
nil,
100100
nil,
101101
nil,
102-
&flow.Header{Height: 1},
102+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
103103
false,
104104
false,
105105
)

cmd/bootstrap/run/block.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ import (
88

99
func GenerateRootHeader(chainID flow.ChainID, parentID flow.Identifier, height uint64, timestamp time.Time) *flow.Header {
1010
return &flow.Header{
11-
ChainID: chainID,
12-
ParentID: parentID,
13-
Height: height,
14-
Timestamp: timestamp,
15-
View: 0,
16-
ParentVoterIndices: nil,
17-
ParentVoterSigData: nil,
18-
ProposerID: flow.ZeroID,
19-
ProposerSigData: nil,
11+
UnsignedHeader: flow.UnsignedHeader{
12+
ChainID: chainID,
13+
ParentID: parentID,
14+
Height: height,
15+
Timestamp: timestamp,
16+
View: 0,
17+
ParentVoterIndices: nil,
18+
ParentVoterSigData: nil,
19+
ProposerID: flow.ZeroID,
20+
},
21+
ProposerSigData: nil,
2022
}
2123
}

cmd/bootstrap/run/cluster_qc_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ func TestGenerateClusterRootQC(t *testing.T) {
2424
block.Header.PayloadHash = block.Payload.Hash()
2525

2626
clusterBlock := cluster.Block{
27-
Header: &flow.Header{
27+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
2828
ParentID: flow.ZeroID,
2929
View: 42,
30-
},
30+
}},
3131
}
3232
payload := cluster.EmptyPayload(flow.ZeroID)
3333
clusterBlock.SetPayload(payload)

consensus/follower_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ func (s *HotStuffFollowerSuite) SetupTest() {
9090
// root block and QC
9191
parentID, err := flow.HexStringToIdentifier("aa7693d498e9a087b1cadf5bfe9a1ff07829badc1915c210e482f369f9a00a70")
9292
require.NoError(s.T(), err)
93-
s.rootHeader = &flow.Header{
93+
s.rootHeader = &flow.Header{UnsignedHeader: flow.UnsignedHeader{
9494
ParentID: parentID,
9595
Timestamp: time.Now().UTC(),
9696
Height: 21053,
9797
View: 52078,
9898
ParentView: 52077,
99-
}
99+
}}
100100

101101
signerIndices, err := signature.EncodeSignersToIndices(identities.NodeIDs(), identities.NodeIDs()[:3])
102102
require.NoError(s.T(), err)

consensus/hotstuff/helper/block.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,18 @@ func SignedProposalToFlow(proposal *model.SignedProposal) *flow.Header {
113113

114114
block := proposal.Block
115115
header := &flow.Header{
116-
ParentID: block.QC.BlockID,
117-
PayloadHash: block.PayloadHash,
118-
Timestamp: block.Timestamp,
119-
View: block.View,
120-
ParentView: block.QC.View,
121-
ParentVoterIndices: block.QC.SignerIndices,
122-
ParentVoterSigData: block.QC.SigData,
123-
ProposerID: block.ProposerID,
124-
ProposerSigData: proposal.SigData,
125-
LastViewTC: proposal.LastViewTC,
116+
UnsignedHeader: flow.UnsignedHeader{
117+
ParentID: block.QC.BlockID,
118+
PayloadHash: block.PayloadHash,
119+
Timestamp: block.Timestamp,
120+
View: block.View,
121+
ParentView: block.QC.View,
122+
ParentVoterIndices: block.QC.SignerIndices,
123+
ParentVoterSigData: block.QC.SigData,
124+
ProposerID: block.ProposerID,
125+
LastViewTC: proposal.LastViewTC,
126+
},
127+
ProposerSigData: proposal.SigData,
126128
}
127129

128130
return header

consensus/hotstuff/integration/defaults_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import (
88
)
99

1010
func DefaultRoot() *flow.Header {
11-
header := &flow.Header{
11+
header := &flow.Header{UnsignedHeader: flow.UnsignedHeader{
1212
ChainID: "chain",
1313
ParentID: flow.ZeroID,
1414
Height: 0,
1515
PayloadHash: unittest.IdentifierFixture(),
1616
Timestamp: time.Now().UTC(),
17-
}
17+
}}
1818
return header
1919
}

consensus/hotstuff/integration/instance_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ func NewInstance(t *testing.T, options ...Option) *Instance {
198198
if !ok {
199199
return nil
200200
}
201-
header := &flow.Header{
201+
header := &flow.Header{UnsignedHeader: flow.UnsignedHeader{
202202
ChainID: "chain",
203203
ParentID: parentID,
204204
ParentView: parent.View,
205205
Height: parent.Height + 1,
206206
PayloadHash: unittest.IdentifierFixture(),
207207
Timestamp: time.Now().UTC(),
208-
}
208+
}}
209209
require.NoError(t, setter(header))
210210
require.NoError(t, sign(header))
211211
in.headers[header.ID()] = header

engine/access/ingestion/engine_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ func (s *Suite) TestExecutionReceiptsAreIndexed() {
431431
// we should store the light collection and index its transactions
432432
s.collections.On("StoreLightAndIndexByTransaction", &light).Return(nil).Once()
433433
block := &flow.Block{
434-
Header: &flow.Header{Height: 0},
434+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 0}},
435435
Payload: &flow.Payload{Guarantees: []*flow.CollectionGuarantee{}},
436436
}
437437
s.blocks.On("ByID", mock.Anything).Return(block, nil)

engine/common/rpc/convert/headers.go

+14-12
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,19 @@ func MessageToBlockHeader(m *entities.BlockHeader) (*flow.Header, error) {
8181
}
8282

8383
return &flow.Header{
84-
ParentID: MessageToIdentifier(m.ParentId),
85-
Height: m.Height,
86-
PayloadHash: MessageToIdentifier(m.PayloadHash),
87-
Timestamp: m.Timestamp.AsTime(),
88-
View: m.View,
89-
ParentView: m.ParentView,
90-
ParentVoterIndices: m.ParentVoterIndices,
91-
ParentVoterSigData: m.ParentVoterSigData,
92-
ProposerID: MessageToIdentifier(m.ProposerId),
93-
ProposerSigData: m.ProposerSigData,
94-
ChainID: *chainId,
95-
LastViewTC: lastViewTC,
84+
UnsignedHeader: flow.UnsignedHeader{
85+
ParentID: MessageToIdentifier(m.ParentId),
86+
Height: m.Height,
87+
PayloadHash: MessageToIdentifier(m.PayloadHash),
88+
Timestamp: m.Timestamp.AsTime(),
89+
View: m.View,
90+
ParentView: m.ParentView,
91+
ParentVoterIndices: m.ParentVoterIndices,
92+
ParentVoterSigData: m.ParentVoterSigData,
93+
ProposerID: MessageToIdentifier(m.ProposerId),
94+
ChainID: *chainId,
95+
LastViewTC: lastViewTC,
96+
},
97+
ProposerSigData: m.ProposerSigData,
9698
}, nil
9799
}

engine/execution/computation/computer/computer_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1620,11 +1620,11 @@ func generateBlockWithVisitor(
16201620
}
16211621

16221622
block := flow.Block{
1623-
Header: &flow.Header{
1623+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
16241624
Timestamp: flow.GenesisTime,
16251625
Height: 42,
16261626
View: 42,
1627-
},
1627+
}},
16281628
Payload: &flow.Payload{
16291629
Guarantees: guarantees,
16301630
},

engine/execution/computation/manager_benchmark_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,10 @@ func createBlock(b *testing.B, parentBlock *flow.Block, accs *testAccounts, colN
282282
}
283283

284284
block := flow.Block{
285-
Header: &flow.Header{
285+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
286286
ParentID: parentBlock.ID(),
287287
View: parentBlock.Header.Height + 1,
288-
},
288+
}},
289289
Payload: &flow.Payload{
290290
Guarantees: guarantees,
291291
},

engine/execution/computation/manager_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ func TestComputeBlockWithStorage(t *testing.T) {
9898
}
9999

100100
block := flow.Block{
101-
Header: &flow.Header{
101+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
102102
View: 42,
103-
},
103+
}},
104104
Payload: &flow.Payload{
105105
Guarantees: []*flow.CollectionGuarantee{&guarantee},
106106
},
@@ -793,9 +793,9 @@ func Test_EventEncodingFailsOnlyTxAndCarriesOn(t *testing.T) {
793793
}
794794

795795
block := flow.Block{
796-
Header: &flow.Header{
796+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
797797
View: 26,
798-
},
798+
}},
799799
Payload: &flow.Payload{
800800
Guarantees: []*flow.CollectionGuarantee{&guarantee},
801801
},

engine/execution/computation/programs_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ func TestPrograms_TestContractUpdates(t *testing.T) {
9292
}
9393

9494
block := flow.Block{
95-
Header: &flow.Header{
95+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
9696
View: 26,
97-
},
97+
}},
9898
Payload: &flow.Payload{
9999
Guarantees: []*flow.CollectionGuarantee{&guarantee},
100100
},
@@ -275,9 +275,9 @@ func TestPrograms_TestBlockForks(t *testing.T) {
275275

276276
t.Run("executing block1 (no collection)", func(t *testing.T) {
277277
block1 = &flow.Block{
278-
Header: &flow.Header{
278+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
279279
View: 1,
280-
},
280+
}},
281281
Payload: &flow.Payload{
282282
Guarantees: []*flow.CollectionGuarantee{},
283283
},
@@ -499,11 +499,11 @@ func createTestBlockAndRun(
499499
}
500500

501501
block := &flow.Block{
502-
Header: &flow.Header{
502+
Header: &flow.Header{UnsignedHeader: flow.UnsignedHeader{
503503
ParentID: parentBlock.ID(),
504504
View: parentBlock.Header.Height + 1,
505505
Timestamp: time.Now(),
506-
},
506+
}},
507507
Payload: &flow.Payload{
508508
Guarantees: []*flow.CollectionGuarantee{&guarantee},
509509
},

engine/execution/ingestion/core_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func createCore(t *testing.T, blocks []*flow.Block) (
116116
headers,
117117
nil,
118118
nil,
119-
&flow.Header{Height: 1},
119+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
120120
false,
121121
false,
122122
)

engine/execution/ingestion/stop/stop_control_test.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestCannotSetNewValuesAfterStoppingCommenced(t *testing.T) {
3131
nil,
3232
nil,
3333
nil,
34-
&flow.Header{Height: 1},
34+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
3535
false,
3636
false,
3737
)
@@ -77,7 +77,7 @@ func TestCannotSetNewValuesAfterStoppingCommenced(t *testing.T) {
7777
nil,
7878
nil,
7979
nil,
80-
&flow.Header{Height: 1},
80+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
8181
false,
8282
false,
8383
)
@@ -133,7 +133,7 @@ func TestExecutionFallingBehind(t *testing.T) {
133133
nil,
134134
nil,
135135
nil,
136-
&flow.Header{Height: 1},
136+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
137137
false,
138138
false,
139139
)
@@ -195,7 +195,7 @@ func TestAddStopForPastBlocks(t *testing.T) {
195195
headers,
196196
nil,
197197
nil,
198-
&flow.Header{Height: 1},
198+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
199199
false,
200200
false,
201201
)
@@ -251,7 +251,7 @@ func TestAddStopForPastBlocksExecutionFallingBehind(t *testing.T) {
251251
headers,
252252
nil,
253253
nil,
254-
&flow.Header{Height: 1},
254+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
255255
false,
256256
false,
257257
)
@@ -304,7 +304,7 @@ func TestStopControlWithVersionControl(t *testing.T) {
304304
headers,
305305
versionBeacons,
306306
semver.New("1.0.0"),
307-
&flow.Header{Height: 1},
307+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
308308
false,
309309
false,
310310
)
@@ -406,7 +406,7 @@ func TestStopControlWithVersionControl(t *testing.T) {
406406
headers,
407407
versionBeacons,
408408
semver.New("1.0.0"),
409-
&flow.Header{Height: 1},
409+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
410410
false,
411411
false,
412412
)
@@ -484,7 +484,7 @@ func TestStopControlWithVersionControl(t *testing.T) {
484484
headers,
485485
versionBeacons,
486486
semver.New("1.0.0"),
487-
&flow.Header{Height: 1},
487+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
488488
false,
489489
false,
490490
)
@@ -562,7 +562,7 @@ func TestStopControlWithVersionControl(t *testing.T) {
562562
headers,
563563
versionBeacons,
564564
semver.New("1.0.0"),
565-
&flow.Header{Height: 1},
565+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
566566
false,
567567
false,
568568
)
@@ -616,7 +616,7 @@ func TestStartingStopped(t *testing.T) {
616616
nil,
617617
nil,
618618
nil,
619-
&flow.Header{Height: 1},
619+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
620620
true,
621621
false,
622622
)
@@ -637,7 +637,7 @@ func TestStoppedStateRejectsAllBlocksAndChanged(t *testing.T) {
637637
nil,
638638
nil,
639639
nil,
640-
&flow.Header{Height: 1},
640+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
641641
true,
642642
false,
643643
)
@@ -667,7 +667,7 @@ func Test_StopControlWorkers(t *testing.T) {
667667
nil,
668668
nil,
669669
nil,
670-
&flow.Header{Height: 1},
670+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
671671
true,
672672
false,
673673
)
@@ -694,7 +694,7 @@ func Test_StopControlWorkers(t *testing.T) {
694694
nil,
695695
nil,
696696
nil,
697-
&flow.Header{Height: 1},
697+
&flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 1}},
698698
false,
699699
false,
700700
)

fvm/fvm_blockcontext_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1683,7 +1683,7 @@ func TestBlockContext_GetAccount(t *testing.T) {
16831683

16841684
func TestBlockContext_Random(t *testing.T) {
16851685
chain, vm := createChainAndVm(flow.Mainnet)
1686-
header := &flow.Header{Height: 42}
1686+
header := &flow.Header{UnsignedHeader: flow.UnsignedHeader{Height: 42}}
16871687
source := testutil.EntropyProviderFixture(nil)
16881688
ctx := fvm.NewContext(
16891689
fvm.WithChain(chain),

integration/dkg/dkg_emulator_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (s *EmulatorSuite) runTest(goodNodes int, emulatorProblems bool) {
6464
FinalView: 600,
6565
}
6666

67-
firstBlock := &flow.Header{View: 100}
67+
firstBlock := &flow.Header{UnsignedHeader: flow.UnsignedHeader{View: 100}}
6868

6969
for _, node := range nodes {
7070
node.setEpochs(s.T(), currentEpochSetup, nextEpochSetup, firstBlock)

0 commit comments

Comments
 (0)