Skip to content

Commit 5ce102b

Browse files
committed
Merge branch 'master' into petera/streaming-execution-data-api
2 parents 0230922 + b93fee7 commit 5ce102b

File tree

70 files changed

+2021
-1266
lines changed

Some content is hidden

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

70 files changed

+2021
-1266
lines changed

admin/command_runner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,15 @@ func NewCommandRunnerBootstrapper() *CommandRunnerBootstrapper {
7676
func (r *CommandRunnerBootstrapper) Bootstrap(logger zerolog.Logger, bindAddress string, opts ...CommandRunnerOption) *CommandRunner {
7777
handlers := make(map[string]CommandHandler)
7878
commands := make([]interface{}, 0, len(r.handlers))
79+
80+
r.RegisterHandler("ping", func(ctx context.Context, req *CommandRequest) (interface{}, error) {
81+
return "pong", nil
82+
})
83+
7984
r.RegisterHandler("list-commands", func(ctx context.Context, req *CommandRequest) (interface{}, error) {
8085
return commands, nil
8186
})
87+
8288
for command, handler := range r.handlers {
8389
handlers[command] = handler
8490
commands = append(commands, command)

cmd/access/node_builder/access_node_builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func DefaultAccessNodeConfig() *AccessNodeConfig {
180180
BindAddress: cmd.NotSet,
181181
Metrics: metrics.NewNoopCollector(),
182182
},
183-
executionDataSyncEnabled: false,
183+
executionDataSyncEnabled: true,
184184
executionDataDir: filepath.Join(homedir, ".flow", "execution_data"),
185185
executionDataStartHeight: 0,
186186
executionDataConfig: edrequester.ExecutionDataConfig{

cmd/observer/node_builder/observer_builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ func NewFlowObserverServiceBuilder(opts ...Option) *ObserverServiceBuilder {
566566
}
567567
anb := &ObserverServiceBuilder{
568568
ObserverServiceConfig: config,
569-
FlowNodeBuilder: cmd.FlowNode(flow.RoleAccess.String()),
569+
FlowNodeBuilder: cmd.FlowNode("observer"),
570570
FinalizationDistributor: pubsub.NewFinalizationDistributor(),
571571
}
572572
anb.FinalizationDistributor.AddConsumer(notifications.NewSlashingViolationsConsumer(anb.Logger))
Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1 @@
11
package forks
2-
3-
import (
4-
"github.com/onflow/flow-go/consensus/hotstuff/model"
5-
"github.com/onflow/flow-go/model/flow"
6-
)
7-
8-
// BlockQC is a Block with a QC that pointing to it, meaning a Quorum Certified Block.
9-
// This implies Block.View == QC.View && Block.BlockID == QC.BlockID
10-
type BlockQC struct {
11-
Block *model.Block
12-
QC *flow.QuorumCertificate
13-
}

consensus/hotstuff/forks/block_builder_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func makeBlockID(block *model.Block) flow.Identifier {
145145
})
146146
}
147147

148-
func makeGenesis() *BlockQC {
148+
func makeGenesis() *model.CertifiedBlock {
149149
genesis := &model.Block{
150150
View: 1,
151151
}
@@ -155,9 +155,9 @@ func makeGenesis() *BlockQC {
155155
View: 1,
156156
BlockID: genesis.BlockID,
157157
}
158-
genesisBQ := &BlockQC{
159-
Block: genesis,
160-
QC: genesisQC,
158+
certifiedGenesisBlock, err := model.NewCertifiedBlock(genesis, genesisQC)
159+
if err != nil {
160+
panic(fmt.Sprintf("combining genesis block and genensis QC to certified block failed: %s", err.Error()))
161161
}
162-
return genesisBQ
162+
return &certifiedGenesisBlock
163163
}

consensus/hotstuff/forks/forks.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ var ErrPrunedAncestry = errors.New("cannot resolve pruned ancestor")
2626
// [b<-qc_b] [b'<-qc_b'] [b*]
2727
type ancestryChain struct {
2828
block *BlockContainer
29-
oneChain *BlockQC
30-
twoChain *BlockQC
29+
oneChain *model.CertifiedBlock
30+
twoChain *model.CertifiedBlock
3131
}
3232

3333
// Forks enforces structural validity of the consensus state and implements
@@ -40,13 +40,13 @@ type Forks struct {
4040
forest forest.LevelledForest
4141

4242
finalizationCallback module.Finalizer
43-
newestView uint64 // newestView is the highest view of block proposal stored in Forks
44-
lastFinalized *BlockQC // lastFinalized is the QC that POINTS TO the most recently finalized locked block
43+
newestView uint64 // newestView is the highest view of block proposal stored in Forks
44+
lastFinalized *model.CertifiedBlock // the most recently finalized block and the QC that certifies it
4545
}
4646

4747
var _ hotstuff.Forks = (*Forks)(nil)
4848

49-
func New(trustedRoot *BlockQC, finalizationCallback module.Finalizer, notifier hotstuff.FinalizationConsumer) (*Forks, error) {
49+
func New(trustedRoot *model.CertifiedBlock, finalizationCallback module.Finalizer, notifier hotstuff.FinalizationConsumer) (*Forks, error) {
5050
if (trustedRoot.Block.BlockID != trustedRoot.QC.BlockID) || (trustedRoot.Block.View != trustedRoot.QC.View) {
5151
return nil, model.NewConfigurationErrorf("invalid root: root QC is not pointing to root block")
5252
}
@@ -341,7 +341,7 @@ func (f *Forks) getTwoChain(blockContainer *BlockContainer) (*ancestryChain, err
341341
// - model.MissingBlockError if the parent block does not exist in the forest
342342
// (but is above the pruned view)
343343
// - generic error in case of unexpected bug or internal state corruption
344-
func (f *Forks) getNextAncestryLevel(block *model.Block) (*BlockQC, error) {
344+
func (f *Forks) getNextAncestryLevel(block *model.Block) (*model.CertifiedBlock, error) {
345345
// The finalizer prunes all blocks in forest which are below the most recently finalized block.
346346
// Hence, we have a pruned ancestry if and only if either of the following conditions applies:
347347
// (a) if a block's parent view (i.e. block.QC.View) is below the most recently finalized block.
@@ -367,9 +367,11 @@ func (f *Forks) getNextAncestryLevel(block *model.Block) (*BlockQC, error) {
367367
block.BlockID, block.View, block.QC.View, block.QC.BlockID, parentBlock.BlockID, parentBlock.View)
368368
}
369369

370-
blockQC := BlockQC{Block: parentBlock, QC: block.QC}
371-
372-
return &blockQC, nil
370+
certifiedBlock, err := model.NewCertifiedBlock(parentBlock, block.QC)
371+
if err != nil {
372+
return nil, fmt.Errorf("constructing certified block failed: %w", err)
373+
}
374+
return &certifiedBlock, nil
373375
}
374376

375377
// finalizeUpToBlock finalizes all blocks up to (and including) the block pointed to by `qc`.
@@ -416,7 +418,10 @@ func (f *Forks) finalizeUpToBlock(qc *flow.QuorumCertificate) error {
416418
}
417419

418420
// finalize block itself:
419-
f.lastFinalized = &BlockQC{Block: block, QC: qc}
421+
*f.lastFinalized, err = model.NewCertifiedBlock(block, qc)
422+
if err != nil {
423+
return fmt.Errorf("constructing certified block failed: %w", err)
424+
}
420425
err = f.forest.PruneUpToLevel(block.View)
421426
if err != nil {
422427
if mempool.IsBelowPrunedThresholdError(err) {

consensus/hotstuff/integration/instance_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,8 @@ func NewInstance(t *testing.T, options ...Option) *Instance {
378378
BlockID: rootBlock.BlockID,
379379
SignerIndices: signerIndices,
380380
}
381-
rootBlockQC := &forks.BlockQC{Block: rootBlock, QC: rootQC}
381+
certifiedRootBlock, err := model.NewCertifiedBlock(rootBlock, rootQC)
382+
require.NoError(t, err)
382383

383384
livenessData := &hotstuff.LivenessData{
384385
CurrentView: rootQC.View + 1,
@@ -393,7 +394,7 @@ func NewInstance(t *testing.T, options ...Option) *Instance {
393394
require.NoError(t, err)
394395

395396
// initialize the forks handler
396-
in.forks, err = forks.New(rootBlockQC, in.finalizer, notifier)
397+
in.forks, err = forks.New(&certifiedRootBlock, in.finalizer, notifier)
397398
require.NoError(t, err)
398399

399400
// initialize the validator

consensus/hotstuff/model/block.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package model
22

33
import (
4+
"fmt"
45
"time"
56

67
"github.com/onflow/flow-go/model/flow"
@@ -44,3 +45,40 @@ func GenesisBlockFromFlow(header *flow.Header) *Block {
4445
}
4546
return genesis
4647
}
48+
49+
// CertifiedBlock holds a certified block, which is a block and a QC that is pointing to
50+
// the block. A QC is the aggregated form of votes from a supermajority of HotStuff and
51+
// therefore proves validity of the block. A certified block satisfies:
52+
// Block.View == QC.View and Block.BlockID == QC.BlockID
53+
type CertifiedBlock struct {
54+
Block *Block
55+
QC *flow.QuorumCertificate
56+
}
57+
58+
// NewCertifiedBlock constructs a new certified block. It checks the consistency
59+
// requirements and returns an exception otherwise:
60+
//
61+
// Block.View == QC.View and Block.BlockID == QC.BlockID
62+
func NewCertifiedBlock(block *Block, qc *flow.QuorumCertificate) (CertifiedBlock, error) {
63+
if block.View != qc.View {
64+
return CertifiedBlock{}, fmt.Errorf("block's view (%d) should equal the qc's view (%d)", block.View, qc.View)
65+
}
66+
if block.BlockID != qc.BlockID {
67+
return CertifiedBlock{}, fmt.Errorf("block's ID (%v) should equal the block referenced by the qc (%d)", block.BlockID, qc.BlockID)
68+
}
69+
return CertifiedBlock{
70+
Block: block,
71+
QC: qc,
72+
}, nil
73+
}
74+
75+
// ID returns unique identifier for the block.
76+
// To avoid repeated computation, we use value from the QC.
77+
func (b *CertifiedBlock) ID() flow.Identifier {
78+
return b.QC.BlockID
79+
}
80+
81+
// View returns view where the block was proposed.
82+
func (b *CertifiedBlock) View() uint64 {
83+
return b.QC.View
84+
}

0 commit comments

Comments
 (0)