diff --git a/chain/store/events.go b/chain/store/events.go index c1cb54157..f1adc1bd7 100644 --- a/chain/store/events.go +++ b/chain/store/events.go @@ -65,7 +65,7 @@ func NewEvents(cs eventChainStore) *Events { cs: cs, tsc: tsc, - confQueue: map[uint64]map[uint64][]queuedEvent{}, + confQueue: map[uint64]map[uint64][]*queuedEvent{}, revertQueue: map[uint64][]uint64{}, triggers: map[uint64]callHandler{}, callTuples: map[callTuple][]uint64{}, diff --git a/chain/store/events_called.go b/chain/store/events_called.go index 4a05273a5..ccb0b0f35 100644 --- a/chain/store/events_called.go +++ b/chain/store/events_called.go @@ -35,6 +35,8 @@ type queuedEvent struct { h uint64 msg *types.Message + + called bool } type calledEvents struct { @@ -47,7 +49,7 @@ type calledEvents struct { // maps block heights to events // [triggerH][msgH][event] - confQueue map[uint64]map[uint64][]queuedEvent + confQueue map[uint64]map[uint64][]*queuedEvent // [msgH][triggerH] revertQueue map[uint64][]uint64 @@ -89,12 +91,19 @@ func (e *calledEvents) handleReverts(ts *types.TipSet) { for _, triggerH := range reverts { toRevert := e.confQueue[triggerH][ts.Height()] for _, event := range toRevert { + if !event.called { + continue // event wasn't apply()-ied yet + } + trigger := e.triggers[event.trigger] + 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) } } + delete(e.confQueue[triggerH], ts.Height()) } + delete(e.revertQueue, ts.Height()) } 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] if !ok { - byOrigH = map[uint64][]queuedEvent{} + byOrigH = map[uint64][]*queuedEvent{} e.confQueue[triggerH] = byOrigH } - byOrigH[ts.Height()] = append(byOrigH[ts.Height()], queuedEvent{ + byOrigH[ts.Height()] = append(byOrigH[ts.Height()], &queuedEvent{ trigger: triggerId, h: ts.Height(), msg: msg, }) + + e.revertQueue[ts.Height()] = append(e.revertQueue[ts.Height()], triggerH) // todo: dedupe? } func (e *calledEvents) applyWithConfidence(ts *types.TipSet) { @@ -149,12 +160,13 @@ func (e *calledEvents) applyWithConfidence(ts *types.TipSet) { for _, event := range events { trigger := e.triggers[event.trigger] + 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) 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) 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("^^^") +}*/ diff --git a/chain/store/events_test.go b/chain/store/events_test.go index a10b9065f..1516d9ca2 100644 --- a/chain/store/events_test.go +++ b/chain/store/events_test.go @@ -4,12 +4,11 @@ import ( "fmt" "github.com/filecoin-project/go-lotus/build" "github.com/filecoin-project/go-lotus/chain/address" - "github.com/multiformats/go-multihash" - "testing" - "github.com/filecoin-project/go-lotus/chain/types" "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" "github.com/stretchr/testify/require" + "testing" ) var dummyCid cid.Cid @@ -309,6 +308,22 @@ func TestCalled(t *testing.T) { 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, reverted) + }