Skip to content

Commit bbe825d

Browse files
authored
Refactor consensus 5 (iotexproject#454)
* Refactor consensus 2 * Reduce number of consensus states * Reduce number of consensus states * Consensus Refactor 4 * address golangci * add endorsements to block footer
1 parent 35cf909 commit bbe825d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3589
-4211
lines changed

action/protocol/execution/protocol_test.go

+72-15
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ func runExecution(
101101
testaddress.Keyinfo["producer"].PubKey,
102102
testaddress.Keyinfo["producer"].PriKey,
103103
testaddress.Addrinfo["producer"].Bech32(),
104-
nil,
105-
nil,
106-
"",
107104
)
108105
if err != nil {
109106
return nil, err
@@ -265,7 +262,12 @@ func TestProtocol_Handle(t *testing.T) {
265262

266263
actionMap := make(map[string][]action.SealedEnvelope)
267264
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
268-
blk, err := bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
265+
blk, err := bc.MintNewBlock(
266+
actionMap,
267+
testaddress.Keyinfo["producer"].PubKey,
268+
testaddress.Keyinfo["producer"].PriKey,
269+
testaddress.Addrinfo["producer"].Bech32(),
270+
)
269271
require.NoError(err)
270272
require.NoError(bc.ValidateBlock(blk, true))
271273
require.Nil(bc.CommitBlock(blk))
@@ -318,7 +320,12 @@ func TestProtocol_Handle(t *testing.T) {
318320

319321
actionMap = make(map[string][]action.SealedEnvelope)
320322
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
321-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
323+
blk, err = bc.MintNewBlock(
324+
actionMap,
325+
testaddress.Keyinfo["producer"].PubKey,
326+
testaddress.Keyinfo["producer"].PriKey,
327+
testaddress.Addrinfo["producer"].Bech32(),
328+
)
322329
require.NoError(err)
323330
require.NoError(bc.ValidateBlock(blk, true))
324331
require.Nil(bc.CommitBlock(blk))
@@ -353,7 +360,12 @@ func TestProtocol_Handle(t *testing.T) {
353360
log.S().Infof("execution %+v", execution)
354361
actionMap = make(map[string][]action.SealedEnvelope)
355362
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
356-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
363+
blk, err = bc.MintNewBlock(
364+
actionMap,
365+
testaddress.Keyinfo["producer"].PubKey,
366+
testaddress.Keyinfo["producer"].PriKey,
367+
testaddress.Addrinfo["producer"].Bech32(),
368+
)
357369
require.NoError(err)
358370
require.NoError(bc.ValidateBlock(blk, true))
359371
require.Nil(bc.CommitBlock(blk))
@@ -378,7 +390,12 @@ func TestProtocol_Handle(t *testing.T) {
378390

379391
actionMap = make(map[string][]action.SealedEnvelope)
380392
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
381-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["alfa"].PubKey, testaddress.Keyinfo["alfa"].PriKey, testaddress.Addrinfo["alfa"].Bech32(), nil, nil, "")
393+
blk, err = bc.MintNewBlock(
394+
actionMap,
395+
testaddress.Keyinfo["alfa"].PubKey,
396+
testaddress.Keyinfo["alfa"].PriKey,
397+
testaddress.Addrinfo["alfa"].Bech32(),
398+
)
382399
require.NoError(err)
383400
require.NoError(bc.ValidateBlock(blk, true))
384401
require.Nil(bc.CommitBlock(blk))
@@ -449,7 +466,12 @@ func TestProtocol_Handle(t *testing.T) {
449466

450467
actionMap := make(map[string][]action.SealedEnvelope)
451468
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
452-
blk, err := bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
469+
blk, err := bc.MintNewBlock(
470+
actionMap,
471+
testaddress.Keyinfo["producer"].PubKey,
472+
testaddress.Keyinfo["producer"].PriKey,
473+
testaddress.Addrinfo["producer"].Bech32(),
474+
)
453475
require.NoError(err)
454476
require.NoError(bc.ValidateBlock(blk, true))
455477
require.Nil(bc.CommitBlock(blk))
@@ -475,7 +497,12 @@ func TestProtocol_Handle(t *testing.T) {
475497

476498
actionMap = make(map[string][]action.SealedEnvelope)
477499
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
478-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
500+
blk, err = bc.MintNewBlock(
501+
actionMap,
502+
testaddress.Keyinfo["producer"].PubKey,
503+
testaddress.Keyinfo["producer"].PriKey,
504+
testaddress.Addrinfo["producer"].Bech32(),
505+
)
479506
require.NoError(err)
480507
require.NoError(bc.ValidateBlock(blk, true))
481508
require.Nil(bc.CommitBlock(blk))
@@ -501,7 +528,12 @@ func TestProtocol_Handle(t *testing.T) {
501528

502529
actionMap = make(map[string][]action.SealedEnvelope)
503530
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
504-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
531+
blk, err = bc.MintNewBlock(
532+
actionMap,
533+
testaddress.Keyinfo["producer"].PubKey,
534+
testaddress.Keyinfo["producer"].PriKey,
535+
testaddress.Addrinfo["producer"].Bech32(),
536+
)
505537
require.NoError(err)
506538
require.NoError(bc.ValidateBlock(blk, true))
507539
require.Nil(bc.CommitBlock(blk))
@@ -534,7 +566,12 @@ func TestProtocol_Handle(t *testing.T) {
534566

535567
actionMap = make(map[string][]action.SealedEnvelope)
536568
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
537-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
569+
blk, err = bc.MintNewBlock(
570+
actionMap,
571+
testaddress.Keyinfo["producer"].PubKey,
572+
testaddress.Keyinfo["producer"].PriKey,
573+
testaddress.Addrinfo["producer"].Bech32(),
574+
)
538575
require.NoError(err)
539576
require.NoError(bc.ValidateBlock(blk, true))
540577
require.Nil(bc.CommitBlock(blk))
@@ -603,7 +640,12 @@ func TestProtocol_Handle(t *testing.T) {
603640

604641
actionMap := make(map[string][]action.SealedEnvelope)
605642
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
606-
blk, err := bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
643+
blk, err := bc.MintNewBlock(
644+
actionMap,
645+
testaddress.Keyinfo["producer"].PubKey,
646+
testaddress.Keyinfo["producer"].PriKey,
647+
testaddress.Addrinfo["producer"].Bech32(),
648+
)
607649
require.NoError(err)
608650
require.NoError(bc.ValidateBlock(blk, true))
609651
require.Nil(bc.CommitBlock(blk))
@@ -677,7 +719,12 @@ func TestProtocol_Handle(t *testing.T) {
677719

678720
actionMap = make(map[string][]action.SealedEnvelope)
679721
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp, selp2}
680-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
722+
blk, err = bc.MintNewBlock(
723+
actionMap,
724+
testaddress.Keyinfo["producer"].PubKey,
725+
testaddress.Keyinfo["producer"].PriKey,
726+
testaddress.Addrinfo["producer"].Bech32(),
727+
)
681728
require.NoError(err)
682729
require.NoError(bc.ValidateBlock(blk, true))
683730
require.Nil(bc.CommitBlock(blk))
@@ -705,7 +752,12 @@ func TestProtocol_Handle(t *testing.T) {
705752

706753
actionMap = make(map[string][]action.SealedEnvelope)
707754
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp3}
708-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["alfa"].PubKey, testaddress.Keyinfo["alfa"].PriKey, testaddress.Addrinfo["alfa"].Bech32(), nil, nil, "")
755+
blk, err = bc.MintNewBlock(
756+
actionMap,
757+
testaddress.Keyinfo["alfa"].PubKey,
758+
testaddress.Keyinfo["alfa"].PriKey,
759+
testaddress.Addrinfo["alfa"].Bech32(),
760+
)
709761
require.NoError(err)
710762
require.NoError(bc.ValidateBlock(blk, true))
711763
require.Nil(bc.CommitBlock(blk))
@@ -727,7 +779,12 @@ func TestProtocol_Handle(t *testing.T) {
727779

728780
actionMap = make(map[string][]action.SealedEnvelope)
729781
actionMap[selp.SrcAddr()] = []action.SealedEnvelope{selp}
730-
blk, err = bc.MintNewBlock(actionMap, testaddress.Keyinfo["producer"].PubKey, testaddress.Keyinfo["producer"].PriKey, testaddress.Addrinfo["producer"].Bech32(), nil, nil, "")
782+
blk, err = bc.MintNewBlock(
783+
actionMap,
784+
testaddress.Keyinfo["producer"].PubKey,
785+
testaddress.Keyinfo["producer"].PriKey,
786+
testaddress.Addrinfo["producer"].Bech32(),
787+
)
731788
require.NoError(err)
732789
require.NoError(bc.ValidateBlock(blk, true))
733790
require.Nil(bc.CommitBlock(blk))

blockchain/block/block.go

+28-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package block
88

99
import (
1010
"bytes"
11+
"time"
1112

1213
"github.com/golang/protobuf/proto"
1314
"github.com/golang/protobuf/ptypes/timestamp"
@@ -24,22 +25,15 @@ import (
2425
"github.com/iotexproject/iotex-core/state/factory"
2526
)
2627

27-
// Footer defines a set of proof of this block
28-
type Footer struct {
29-
// endorsements contain COMMIT endorsements from more than 2/3 delegates
30-
endorsements *endorsement.Set
31-
commitTimestamp uint64
32-
}
33-
3428
// Block defines the struct of block
3529
type Block struct {
3630
Header
31+
Footer
3732

3833
Actions []action.SealedEnvelope
3934
SecretProposals []*action.SecretProposal
4035
SecretWitness *action.SecretWitness
4136
Receipts map[hash.Hash32B]*action.Receipt
42-
Footer *Footer
4337

4438
WorkingSet factory.WorkingSet
4539
}
@@ -89,7 +83,11 @@ func (b *Block) ConvertToBlockPb() *iproto.BlockPb {
8983
for _, act := range b.Actions {
9084
actions = append(actions, act.Proto())
9185
}
92-
return &iproto.BlockPb{Header: b.ConvertToBlockHeaderPb(), Actions: actions}
86+
return &iproto.BlockPb{
87+
Header: b.ConvertToBlockHeaderPb(),
88+
Actions: actions,
89+
Footer: b.ConvertToBlockFooterPb(),
90+
}
9391
}
9492

9593
// Serialize returns the serialized byte stream of the block
@@ -131,7 +129,8 @@ func (b *Block) ConvertFromBlockPb(pbBlock *iproto.BlockPb) error {
131129
b.Actions = append(b.Actions, act)
132130
// TODO handle SecretProposal and SecretWitness
133131
}
134-
return nil
132+
133+
return b.ConvertFromBlockFooterPb(pbBlock.GetFooter())
135134
}
136135

137136
// Deserialize parses the byte stream into a Block
@@ -215,3 +214,22 @@ func (b *Block) RunnableActions() RunnableActions {
215214
actions: b.Actions,
216215
}
217216
}
217+
218+
// Finalize creates a footer for the block
219+
func (b *Block) Finalize(set *endorsement.Set, round uint32, ts time.Time) error {
220+
if b.endorsements != nil {
221+
return errors.New("the block has been finalized")
222+
}
223+
if set == nil {
224+
return errors.New("endorsement set is nil")
225+
}
226+
commitEndorsements, err := set.SubSet(endorsement.COMMIT)
227+
if err != nil {
228+
return err
229+
}
230+
b.round = round
231+
b.endorsements = commitEndorsements
232+
b.commitTimestamp = ts.Unix()
233+
234+
return nil
235+
}

blockchain/block/footer.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2019 IoTeX
2+
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
3+
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
4+
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
5+
// License 2.0 that can be found in the LICENSE file.
6+
7+
package block
8+
9+
import (
10+
"github.com/iotexproject/iotex-core/endorsement"
11+
"github.com/iotexproject/iotex-core/proto"
12+
)
13+
14+
// Footer defines a set of proof of this block
15+
type Footer struct {
16+
// endorsements contain COMMIT endorsements from more than 2/3 delegates
17+
endorsements *endorsement.Set
18+
commitTimestamp int64
19+
round uint32
20+
}
21+
22+
// ConvertToBlockFooterPb converts BlockFooterPb
23+
func (f *Footer) ConvertToBlockFooterPb() *iproto.BlockFooterPb {
24+
pb := iproto.BlockFooterPb{}
25+
pb.CommitTimestamp = f.commitTimestamp
26+
if f.endorsements != nil {
27+
pb.Endorsements = f.endorsements.ToProto()
28+
}
29+
pb.Round = f.round
30+
31+
return &pb
32+
}
33+
34+
// ConvertFromBlockFooterPb converts BlockFooterPb to BlockFooter
35+
func (f *Footer) ConvertFromBlockFooterPb(pb *iproto.BlockFooterPb) error {
36+
f.round = pb.GetRound()
37+
f.commitTimestamp = pb.GetCommitTimestamp()
38+
pbEndorsements := pb.GetEndorsements()
39+
if pbEndorsements == nil {
40+
return nil
41+
}
42+
f.endorsements = &endorsement.Set{}
43+
44+
return f.endorsements.FromProto(pbEndorsements)
45+
}
46+
47+
// CommitTime returns the timestamp the block was committed
48+
func (f *Footer) CommitTime() int64 {
49+
return f.commitTimestamp
50+
}
51+
52+
// NumOfDelegateEndorsements returns the number of commit endorsements froms delegates
53+
func (f *Footer) NumOfDelegateEndorsements(delegates []string) int {
54+
if f.endorsements == nil {
55+
return 0
56+
}
57+
return f.endorsements.NumOfValidEndorsements(
58+
map[endorsement.ConsensusVoteTopic]bool{endorsement.COMMIT: true},
59+
delegates,
60+
)
61+
}
62+
63+
// Round returns the round the consensus was reached
64+
func (f *Footer) Round() uint32 {
65+
if f.endorsements == nil {
66+
return 0
67+
}
68+
69+
return f.endorsements.Round()
70+
}

0 commit comments

Comments
 (0)