chain events: Fix some edge cases

This commit is contained in:
Łukasz Magiera 2019-09-04 20:56:06 +02:00
parent 289470a466
commit 56b5574a72
3 changed files with 52 additions and 8 deletions

View File

@ -65,7 +65,7 @@ func NewEvents(cs eventChainStore) *Events {
cs: cs, cs: cs,
tsc: tsc, tsc: tsc,
confQueue: map[uint64]map[uint64][]queuedEvent{}, confQueue: map[uint64]map[uint64][]*queuedEvent{},
revertQueue: map[uint64][]uint64{}, revertQueue: map[uint64][]uint64{},
triggers: map[uint64]callHandler{}, triggers: map[uint64]callHandler{},
callTuples: map[callTuple][]uint64{}, callTuples: map[callTuple][]uint64{},

View File

@ -35,6 +35,8 @@ type queuedEvent struct {
h uint64 h uint64
msg *types.Message msg *types.Message
called bool
} }
type calledEvents struct { type calledEvents struct {
@ -47,7 +49,7 @@ type calledEvents struct {
// maps block heights to events // maps block heights to events
// [triggerH][msgH][event] // [triggerH][msgH][event]
confQueue map[uint64]map[uint64][]queuedEvent confQueue map[uint64]map[uint64][]*queuedEvent
// [msgH][triggerH] // [msgH][triggerH]
revertQueue map[uint64][]uint64 revertQueue map[uint64][]uint64
@ -89,12 +91,19 @@ func (e *calledEvents) handleReverts(ts *types.TipSet) {
for _, triggerH := range reverts { for _, triggerH := range reverts {
toRevert := e.confQueue[triggerH][ts.Height()] toRevert := e.confQueue[triggerH][ts.Height()]
for _, event := range toRevert { for _, event := range toRevert {
if !event.called {
continue // event wasn't apply()-ied yet
}
trigger := e.triggers[event.trigger] trigger := e.triggers[event.trigger]
if err := trigger.revert(ts); err != nil { if err := trigger.revert(ts); err != nil {
log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err) log.Errorf("reverting chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, ts.Height(), triggerH, err)
} }
} }
delete(e.confQueue[triggerH], ts.Height())
} }
delete(e.revertQueue, ts.Height())
} }
func (e *calledEvents) checkNewCalls(ts *types.TipSet) error { func (e *calledEvents) checkNewCalls(ts *types.TipSet) error {
@ -124,15 +133,17 @@ func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message,
byOrigH, ok := e.confQueue[triggerH] byOrigH, ok := e.confQueue[triggerH]
if !ok { if !ok {
byOrigH = map[uint64][]queuedEvent{} byOrigH = map[uint64][]*queuedEvent{}
e.confQueue[triggerH] = byOrigH e.confQueue[triggerH] = byOrigH
} }
byOrigH[ts.Height()] = append(byOrigH[ts.Height()], queuedEvent{ byOrigH[ts.Height()] = append(byOrigH[ts.Height()], &queuedEvent{
trigger: triggerId, trigger: triggerId,
h: ts.Height(), h: ts.Height(),
msg: msg, msg: msg,
}) })
e.revertQueue[ts.Height()] = append(e.revertQueue[ts.Height()], triggerH) // todo: dedupe?
} }
func (e *calledEvents) applyWithConfidence(ts *types.TipSet) { func (e *calledEvents) applyWithConfidence(ts *types.TipSet) {
@ -149,12 +160,13 @@ func (e *calledEvents) applyWithConfidence(ts *types.TipSet) {
for _, event := range events { for _, event := range events {
trigger := e.triggers[event.trigger] trigger := e.triggers[event.trigger]
if err := trigger.handle(event.msg, triggerTs, ts.Height()); err != nil { if err := trigger.handle(event.msg, triggerTs, ts.Height()); err != nil {
log.Errorf("chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, origH, ts.Height(), err) log.Errorf("chain trigger (call %s.%d() @H %d, called @ %d) failed: %s", event.msg.To, event.msg.Method, origH, ts.Height(), err)
continue // don't revert failed calls continue // don't revert failed calls
} }
e.revertQueue[origH] = append(e.revertQueue[origH], ts.Height()) event.called = true
} }
} }
} }
@ -225,3 +237,20 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
e.callTuples[ct] = append(e.callTuples[ct], id) e.callTuples[ct] = append(e.callTuples[ct], id)
return nil return nil
} }
/*func (e *calledEvents) debugInfo() {
fmt.Println("vvv")
fmt.Println("@", e.tsc.best().Height())
for k, v := range e.revertQueue {
fmt.Println("revert (msgH->trigH)", k, v)
}
for triggerH, v := range e.confQueue {
for msgh, e := range v {
for _, evt := range e {
fmt.Printf("T@ %d, M@ %d, EH %d, T %d, called %t\n", triggerH, msgh, evt.h, evt.trigger, evt.called)
}
}
}
fmt.Println("^^^")
}*/

View File

@ -4,12 +4,11 @@ import (
"fmt" "fmt"
"github.com/filecoin-project/go-lotus/build" "github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/address"
"github.com/multiformats/go-multihash"
"testing"
"github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing"
) )
var dummyCid cid.Cid var dummyCid cid.Cid
@ -309,6 +308,22 @@ func TestCalled(t *testing.T) {
0: n2msg, 0: n2msg,
}) })
require.Equal(t, true, applied)
require.Equal(t, false, reverted)
applied = false
// send and revert below confidence, then cross confidence
fcs.advance(0, 1, map[int]cid.Cid{ // msg at H=16; H=16
0: fcs.fakeMsgs(fakeMsg{
bmsgs: []*types.Message{
{To: t0123, Method: 5, Nonce: 3},
},
}),
})
fcs.advance(1, 4, nil) // H=19, but message reverted
require.Equal(t, false, applied) require.Equal(t, false, applied)
require.Equal(t, false, reverted) require.Equal(t, false, reverted)
} }