diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go index fd9201454549ffba46b7d77f1ddb393182ad8c68..23012e4a5cc7e0c1e208f75588860171070759f6 100644 --- a/manager/eris-mint/transactor.go +++ b/manager/eris-mint/transactor.go @@ -205,13 +205,24 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } else { addr = address } - wc := make(chan *txs.EventDataCall) + // We want non-blocking on the first event received (but buffer the value), + // after which we want to block (and then discard the value - see below) + wc := make(chan *txs.EventDataCall, 1) subId := fmt.Sprintf("%X", rec.TxHash) this.eventEmitter.Subscribe(subId, txs.EventStringAccCall(addr), func(evt txs.EventData) { - event := evt.(txs.EventDataCall) - if bytes.Equal(event.TxID, rec.TxHash) { - wc <- &event + eventDataCall := evt.(txs.EventDataCall) + if bytes.Equal(eventDataCall.TxID, rec.TxHash) { + // Beware the contract of go-events subscribe is that we must not be + // blocking in an event callback when we try to unsubscribe! + // We work around this by using a non-blocking send. + select { + // This is a non-blocking send, but since we are using a buffered + // channel of size 1 we will always grab our first event even if we + // haven't read from the channel at the time we receive the first event. + case wc <- &eventDataCall: + default: + } } })