Skip to content

Commit

Permalink
add disputes coordinator
Browse files Browse the repository at this point in the history
  • Loading branch information
kanishkatn committed Jul 21, 2023
1 parent ee86336 commit f5f40ac
Showing 1 changed file with 143 additions and 0 deletions.
143 changes: 143 additions & 0 deletions dot/parachain/dispute/coordinator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package dispute

import (
"fmt"
"github.com/ChainSafe/gossamer/dot/parachain/dispute/types"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/lib/parachain"
"github.com/dgraph-io/badger/v4"
"github.com/google/btree"
"time"
)

// CoordinatorSubsystem is the dispute coordinator subsystem interface.
type CoordinatorSubsystem interface {
// Run runs the dispute coordinator subsystem.
Run() error
}

// disputeCoordinator implements the CoordinatorSubsystem interface.
type disputeCoordinator struct {
store *OverlayBackend
blockState state.BlockState
}

func (d *disputeCoordinator) Run() error {
if err := d.initialize(); err != nil {
return fmt.Errorf("initialize dispute coordinator: %w", err)
}

// TODO: run the subsystem

return nil
}

func (d *disputeCoordinator) initialize() error {
// TODO: wait for the first leaf

if err := d.handleStartup(); err != nil {
return fmt.Errorf("handle startup: %w", err)
}

// TODO: update db on disk

//TODO implement me
panic("implement me")
}

func (d *disputeCoordinator) handleStartup() error {
var now = time.Now().Unix()
activeDisputes, err := d.store.GetActiveDisputes(now)
if err != nil {
return fmt.Errorf("get active disputes: %w", err)
}

// get the highest session
bestBlockHash := d.blockState.BestBlockHash()
runtime, err := d.blockState.GetRuntime(bestBlockHash)
if err != nil {
return fmt.Errorf("getting runtime: %w", err)
}

highestSession, err := runtime.ParachainHostSessionIndexForChild()
if err != nil {
return fmt.Errorf("getting highest session: %w", err)
}

// TODO: check if there is a gap in cache

// prune obsolete disputes
if err := d.noteEarliestSession(highestSession); err != nil {
return fmt.Errorf("note earliest session: %w", err)
}

// TODO: for every dispute in activeDisputes
// get candidate votes
// check if it is a potential spam
// participate if needed, if not distribute the own vote
activeDisputes.Descend(func(i btree.Item) bool {
return true
})

return nil
}

func (d *disputeCoordinator) noteEarliestSession(session parachain.SessionIndex) error {
if d.store.earliestSession == nil {
d.store.earliestSession = &session
return nil
}

if *d.store.earliestSession > session {
d.store.earliestSession = &session
// clear recent disputes metadata
recentDisputes, err := d.store.GetRecentDisputes()
if err != nil {
return fmt.Errorf("get recent disputes: %w", err)
}

// determine new recent disputes
newRecentDisputes := btree.New(32)
recentDisputes.Ascend(func(item btree.Item) bool {
dispute := item.(*types.Dispute)
if dispute.Comparator.SessionIndex >= session {
newRecentDisputes.ReplaceOrInsert(dispute)
return true
}
return false
})

// prune obsolete disputes
recentDisputes.Ascend(func(item btree.Item) bool {
dispute := item.(*types.Dispute)
if dispute.Comparator.SessionIndex < session {
recentDisputes.Delete(dispute)
return true
}
return false
})

// update db
if recentDisputes.Len() > 0 {
if err = d.store.SetRecentDisputes(newRecentDisputes); err != nil {
return fmt.Errorf("set recent disputes: %w", err)
}
}
}

return nil
}

func NewDisputeCoordinator() (CoordinatorSubsystem, error) {
// TODO: figure out where to store the db
path := ""
db, err := badger.Open(badger.DefaultOptions(path))
if err != nil {
return nil, fmt.Errorf("open badger db: %w", err)
}
backend := NewOverlayBackend(db)

return &disputeCoordinator{
store: backend,
}, nil
}

0 comments on commit f5f40ac

Please sign in to comment.