Skip to content
This repository has been archived by the owner on Jun 17, 2022. It is now read-only.

LRU-based ordering buffer #327

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/event_check/epoch_check/epoch_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ var (
)

type DagReader interface {
GetEpoch() idx.Epoch
GetMembers() pos.Members
GetEpochMembers() (pos.Members, idx.Epoch)
}

// Check which require only current epoch info
Expand All @@ -33,10 +32,12 @@ func New(config *lachesis.DagConfig, reader DagReader) *Validator {
}

func (v *Validator) Validate(e *inter.Event) error {
if e.Epoch != v.reader.GetEpoch() {
// check epoch first, because validators group is known only for the current epoch
members, epoch := v.reader.GetEpochMembers()
if e.Epoch != epoch {
return ErrNotRecent
}
if _, ok := v.reader.GetMembers()[e.Creator]; !ok {
if _, ok := members[e.Creator]; !ok {
return ErrAuth
}
return nil
Expand Down
2 changes: 2 additions & 0 deletions src/gossip/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Consensus interface {
GetEpoch() idx.Epoch
// GetMembers returns members of current epoch.
GetMembers() pos.Members
// GetEpochMembers atomically returns members of current epoch, and the epoch.
GetEpochMembers() (pos.Members, idx.Epoch)

// Bootstrap must be called (once) before calling other methods
Bootstrap(applyBlock inter.ApplyBlockFn)
Expand Down
7 changes: 7 additions & 0 deletions src/gossip/poset_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ func (hook *HookedEngine) GetEpoch() idx.Epoch {
return hook.engine.GetEpoch()
}

func (hook *HookedEngine) GetEpochMembers() (pos.Members, idx.Epoch) {
if hook.engine == nil {
return pos.Members{}, 1
}
return hook.engine.GetEpochMembers()
}

func (hook *HookedEngine) LastBlock() (idx.Block, hash.Event) {
if hook.engine == nil {
return idx.Block(1), hash.ZeroEvent
Expand Down
5 changes: 5 additions & 0 deletions src/poset/epoch.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func (p *Poset) GetMembers() pos.Members {
return p.Members.Copy()
}

// GetEpochMembers atomically returns members of current epoch, and the epoch.
func (p *Poset) GetEpochMembers() (pos.Members, idx.Epoch) {
return p.GetMembers(), p.GetEpoch() // TODO atomic
}

// rootForklessCausesRoot returns hash of root B, if root A forkless causes root B.
// Due to a fork, there may be many roots B with the same slot,
// but forkless caused may be only one of them (if no more than 1/3n are Byzantine), with a specific hash.
Expand Down
12 changes: 4 additions & 8 deletions src/poset/poset.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,8 @@ func (p *Poset) LastBlock() (idx.Block, hash.Event) {
// fills consensus-related fields: Frame, IsRoot, MedianTimestamp
// returns nil if event should be dropped
func (p *Poset) Prepare(e *inter.Event) *inter.Event {
if e.Epoch != p.EpochN {
p.Log.Info("Event is too old/too new", "event", e.String(), "epoch", e.Epoch, "expect", p.EpochN)
return nil
}
if _, ok := p.Members[e.Creator]; !ok {
p.Log.Warn("Creator isn't a member", "creator", e.Creator.String())
if err := epoch_check.New(&p.dag, p).Validate(e); err != nil {
p.Log.Error("Event prepare error", "err", err)
return nil
}
id := e.Hash() // remember, because we change event here
Expand Down Expand Up @@ -169,8 +165,8 @@ func (p *Poset) processKnownRoots() *election.ElectionRes {
// Event order matter: parents first.
// ProcessEvent is not safe for concurrent use.
func (p *Poset) ProcessEvent(e *inter.Event) error {
if e.Epoch != p.EpochN {
return epoch_check.ErrNotRecent
if err := epoch_check.New(&p.dag, p).Validate(e); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider to cache an epochCheck (epoch_check.New(&p.dag, p)) per poset.
Line 58, 168: epoch_check.New(&p.dag, p).Validate(e) => possibly store a local boolean in the poset for e, if validation takes time.

return err
}
p.Log.Debug("start event processing", "event", e.String())

Expand Down