2019-09-05 07:40:50 +00:00
|
|
|
package events
|
2019-09-03 17:45:55 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
2019-09-05 07:40:50 +00:00
|
|
|
logging "github.com/ipfs/go-log"
|
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"
|
|
|
|
)
|
|
|
|
|
2019-09-05 07:40:50 +00:00
|
|
|
var log = logging.Logger("events")
|
|
|
|
|
2019-09-03 17:45:55 +00:00
|
|
|
// `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 {
|
2019-09-05 07:36:11 +00:00
|
|
|
cs eventChainStore
|
2019-09-03 17:45:55 +00:00
|
|
|
|
|
|
|
tsc *tipSetCache
|
|
|
|
lk sync.Mutex
|
|
|
|
|
2019-09-05 07:36:11 +00:00
|
|
|
heightEvents
|
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{
|
2019-09-05 07:36:11 +00:00
|
|
|
cs: cs,
|
2019-09-03 17:45:55 +00:00
|
|
|
|
2019-09-04 16:09:08 +00:00
|
|
|
tsc: tsc,
|
2019-09-03 17:45:55 +00:00
|
|
|
|
2019-09-05 07:36:11 +00:00
|
|
|
heightEvents: heightEvents{
|
|
|
|
tsc: tsc,
|
|
|
|
gcConfidence: uint64(gcConfidence),
|
|
|
|
|
|
|
|
heightTriggers: map[uint64]*heightHandler{},
|
|
|
|
htTriggerHeights: map[uint64][]uint64{},
|
|
|
|
htHeights: map[uint64][]uint64{},
|
|
|
|
},
|
2019-09-03 17:45:55 +00:00
|
|
|
|
2019-09-04 16:09:08 +00:00
|
|
|
calledEvents: calledEvents{
|
2019-09-05 07:36:11 +00:00
|
|
|
cs: cs,
|
|
|
|
tsc: tsc,
|
|
|
|
gcConfidence: uint64(gcConfidence),
|
2019-09-04 16:09:08 +00:00
|
|
|
|
2019-09-05 07:31:16 +00:00
|
|
|
confQueue: map[triggerH]map[msgH][]*queuedEvent{},
|
|
|
|
revertQueue: map[msgH][]triggerH{},
|
|
|
|
triggers: map[triggerId]*callHandler{},
|
|
|
|
callTuples: map[callTuple][]triggerId{},
|
|
|
|
timeouts: map[uint64]map[triggerId]int{},
|
2019-09-04 16:09:08 +00:00
|
|
|
},
|
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)
|
|
|
|
}
|