Skip to content

Commit

Permalink
rough(sentinel): implement standalone lotus-sentinel binary
Browse files Browse the repository at this point in the history
- includes cli command to start a watch that logs
tipsets as they are received. closes filecoin-project/sentinel#179
  • Loading branch information
frrist committed Feb 26, 2021
1 parent c9c26ee commit 3e7a0f7
Show file tree
Hide file tree
Showing 11 changed files with 666 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
/lotus-pcr
/lotus-wallet
/lotus-keygen
/lotus-sentinel
/bench.json
/lotuspond/front/node_modules
/lotuspond/front/build
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ lotus-keygen:
.PHONY: lotus-keygen
BINS+=lotus-keygen

lotus-sentinel: $(BUILD_DEPS)
rm -f lotus-sentinel
go build -o lotus-sentinel ./cmd/lotus-sentinel
.PHONY: lotus-keygen
BINS+=lotus-sentinel

testground:
go build -tags testground -o /dev/null ./cmd/lotus
.PHONY: testground
Expand Down
54 changes: 47 additions & 7 deletions chain/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ type Events struct {

heightEvents
*hcEvents
}

func NewEvents(ctx context.Context, api eventAPI) *Events {
gcConfidence := 2 * build.ForkLengthThreshold
observers []TipSetObserver
}

func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi.ChainEpoch) *Events {
tsc := newTSCache(gcConfidence, api)

e := &Events{
Expand All @@ -77,8 +77,9 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
htHeights: map[abi.ChainEpoch][]uint64{},
},

hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
ready: make(chan struct{}),
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
ready: make(chan struct{}),
observers: []TipSetObserver{},
}

go e.listenHeadChanges(ctx)
Expand All @@ -92,6 +93,11 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
return e
}

func NewEvents(ctx context.Context, api eventAPI) *Events {
gcConfidence := 2 * build.ForkLengthThreshold
return NewEventsWithConfidence(ctx, api, gcConfidence)
}

func (e *Events) listenHeadChanges(ctx context.Context) {
for {
if err := e.listenHeadChangesOnce(ctx); err != nil {
Expand Down Expand Up @@ -164,7 +170,7 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
}
}

if err := e.headChange(rev, app); err != nil {
if err := e.headChange(ctx, rev, app); err != nil {
log.Warnf("headChange failed: %s", err)
}

Expand All @@ -177,7 +183,7 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
return nil
}

func (e *Events) headChange(rev, app []*types.TipSet) error {
func (e *Events) headChange(ctx context.Context, rev, app []*types.TipSet) error {
if len(app) == 0 {
return xerrors.New("events.headChange expected at least one applied tipset")
}
Expand All @@ -189,5 +195,39 @@ func (e *Events) headChange(rev, app []*types.TipSet) error {
return err
}

if err := e.observeChanges(ctx, rev, app); err != nil {
return err
}
return e.processHeadChangeEvent(rev, app)
}

// A TipSetObserver receives notifications of tipsets
type TipSetObserver interface {
Apply(ctx context.Context, ts *types.TipSet) error
Revert(ctx context.Context, ts *types.TipSet) error
}

// TODO: add a confidence level so we can have observers with difference levels of confidence
func (e *Events) Observe(obs TipSetObserver) error {
e.lk.Lock()
defer e.lk.Unlock()
e.observers = append(e.observers, obs)
return nil
}

// observeChanges expects caller to hold e.lk
func (e *Events) observeChanges(ctx context.Context, rev, app []*types.TipSet) error {
for _, ts := range rev {
for _, o := range e.observers {
_ = o.Revert(ctx, ts)
}
}

for _, ts := range app {
for _, o := range e.observers {
_ = o.Apply(ctx, ts)
}
}

return nil
}
49 changes: 49 additions & 0 deletions cmd/lotus-sentinel/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package api

import (
"context"

logging "github.com/ipfs/go-log/v2"
"go.uber.org/fx"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apistruct"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/node/impl"
"github.com/filecoin-project/lotus/sentinel"
)

var log = logging.Logger("sentinel")

type SentinelNode interface {
api.FullNode
SentinelWatchStart(ctx context.Context) error
}

type SentinelNodeAPI struct {
fx.In

impl.FullNodeAPI
Events *events.Events
}

func (m *SentinelNodeAPI) SentinelWatchStart(ctx context.Context) error {
log.Info("starting sentinel watch")
return m.Events.Observe(&sentinel.LoggingTipSetObserver{})
}

var _ SentinelNode = &SentinelNodeAPI{}

type SentinelNodeStruct struct {
apistruct.FullNodeStruct

Internal struct {
SentinelWatchStart func(context.Context) error `perm:"read"`
}
}

func (s *SentinelNodeStruct) SentinelWatchStart(ctx context.Context) error {
return s.Internal.SentinelWatchStart(ctx)
}

var _ SentinelNode = &SentinelNodeStruct{}
Loading

0 comments on commit 3e7a0f7

Please sign in to comment.