lotus/chain/store/events.go

97 lines
1.9 KiB
Go
Raw Normal View History

2019-09-03 17:45:55 +00:00
package store
import (
"sync"
2019-09-04 16:09:08 +00:00
"golang.org/x/xerrors"
2019-09-03 17:45:55 +00:00
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/types"
)
// `curH`-`ts.Height` = `confidence`
2019-09-04 16:09:08 +00:00
type HeightHandler func(ts *types.TipSet, curH uint64) error
type RevertHandler func(ts *types.TipSet) error
2019-09-03 17:45:55 +00:00
2019-09-04 16:09:08 +00:00
type heightHandler struct {
2019-09-03 17:45:55 +00:00
confidence int
2019-09-04 16:09:08 +00:00
handle HeightHandler
revert RevertHandler
2019-09-03 17:45:55 +00:00
}
type eventChainStore interface {
SubscribeHeadChanges(f func(rev, app []*types.TipSet) error)
GetHeaviestTipSet() *types.TipSet
MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
}
type Events struct {
cs eventChainStore
gcConfidence uint64
tsc *tipSetCache
lk sync.Mutex
ctr uint64
// ChainAt
2019-09-04 16:09:08 +00:00
heightTriggers map[uint64]*heightHandler
2019-09-03 17:45:55 +00:00
htTriggerHeights map[uint64][]uint64
htHeights map[uint64][]uint64
2019-09-04 16:09:08 +00:00
calledEvents
2019-09-03 17:45:55 +00:00
}
func NewEvents(cs eventChainStore) *Events {
gcConfidence := 2 * build.ForkLengthThreshold
2019-09-04 16:09:08 +00:00
tsc := newTSCache(gcConfidence)
2019-09-03 17:45:55 +00:00
e := &Events{
cs: cs,
gcConfidence: uint64(gcConfidence),
2019-09-04 16:09:08 +00:00
tsc: tsc,
2019-09-03 17:45:55 +00:00
2019-09-04 16:09:08 +00:00
heightTriggers: map[uint64]*heightHandler{},
2019-09-03 17:45:55 +00:00
htTriggerHeights: map[uint64][]uint64{},
htHeights: map[uint64][]uint64{},
2019-09-04 16:09:08 +00:00
calledEvents: calledEvents{
cs: cs,
tsc: tsc,
confQueue: map[uint64]map[uint64][]queuedEvent{},
revertQueue: map[uint64][]uint64{},
triggers: map[uint64]callHandler{},
callTuples: map[callTuple][]uint64{},
},
2019-09-03 17:45:55 +00:00
}
_ = e.tsc.add(cs.GetHeaviestTipSet())
cs.SubscribeHeadChanges(e.headChange)
2019-09-03 17:59:32 +00:00
// TODO: cleanup/gc goroutine
2019-09-03 17:45:55 +00:00
return e
}
func (e *Events) headChange(rev, app []*types.TipSet) error {
2019-09-03 17:59:32 +00:00
if len(app) == 0 {
return xerrors.New("events.headChange expected at least one applied tipset")
}
2019-09-03 17:45:55 +00:00
e.lk.Lock()
defer e.lk.Unlock()
2019-09-03 17:59:32 +00:00
if err := e.headChangeAt(rev, app); err != nil {
return err
2019-09-03 17:45:55 +00:00
}
2019-09-03 17:59:32 +00:00
return e.headChangeCalled(rev, app)
}