Burrow, executionEventsServer
ExecutionEventsServer is the server API for ExecutionEvents service.
Data Structure
type executionEventsServer struct {
eventsProvider Provider
emitter *event.Emitter
tip bcm.BlockchainInfo
logger *logging.Logger
}
rpcevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(kern.State,
kern.Emitter, kern.Blockchain, kern.Logger))
It is started with GRPC, and eventsProvider is actually the kern.State which implements:
type Provider interface {
// Get transactions
IterateStreamEvents(start, end *uint64, consumer func(*exec.StreamEvent) error) (err error)
// Get a particular TxExecution by hash
TxByHash(txHash []byte) (*exec.TxExecution, error)
}
Interface
Stream and Events can provide a range of data in stream mode, when stream bound is specified.
// ExecutionEventsServer is the server API for ExecutionEvents service.
type ExecutionEventsServer interface {
// Get StreamEvents (including transactions) for a range of block heights
Stream(*BlocksRequest, ExecutionEvents_StreamServer) error
// Get a particular TxExecution by hash
Tx(context.Context, *TxRequest) (*exec.TxExecution, error)
// GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
// are guaranteed to be delivered in each GetEventsResponse
Events(*BlocksRequest, ExecutionEvents_EventsServer) error
}
Parameter
Bound_BoundType = Bound_STREAM means streaming mode.
type BlockRange struct {
// Bounds can be set to:
// absolute: block height
// relative: block height counting back from latest
// latest: latest block when call is processed
// stream: for End keep sending new blocks, for start same as latest
Start *Bound `protobuf:"bytes,1,opt,name=Start,proto3" json:"Start,omitempty"`
End *Bound `protobuf:"bytes,2,opt,name=End,proto3" json:"End,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
type Bound struct {
Type Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=rpcevents.Bound_BoundType" json:"Type,omitempty"`
Index uint64 `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
const (
// Index is absolute index of an item
Bound_ABSOLUTE Bound_BoundType = 0
// Index is an offset relative to last item
Bound_RELATIVE Bound_BoundType = 1
// The first block
Bound_FIRST Bound_BoundType = 2
// Ignore provided index and evaluate to latest index
Bound_LATEST Bound_BoundType = 3
// Ignore provided index and stream new objects as they are generated
Bound_STREAM Bound_BoundType = 4
)
Call stack
Shown below:
github.com/hyperledger/burrow/rpc/rpcevents.(*executionEventsServer).iterateStreamEvents at execution_events_server.go:205
github.com/hyperledger/burrow/rpc/rpcevents.(*executionEventsServer).streamEvents at execution_events_server.go:128
github.com/hyperledger/burrow/rpc/rpcevents.(*executionEventsServer).Stream at execution_events_server.go:75
github.com/hyperledger/burrow/rpc/rpcevents._ExecutionEvents_Stream_Handler at rpcevents.pb.go:792
github.com/hyperledger/burrow/rpc.streamInterceptor.func1 at grpc.go:45
google.golang.org/grpc.(*Server).processStreamingRPC at server.go:1244
google.golang.org/grpc.(*Server).handleStream at server.go:1317
google.golang.org/grpc.(*Server).serveStreams.func1.1 at server.go:722
runtime.goexit at asm_amd64.s:1357
- Async stack trace
google.golang.org/grpc.(*Server).serveStreams.func1 at server.go:720
iterateStreamEvents
It will invoke the provider to iterate the events…
func (ees *executionEventsServer) iterateStreamEvents(startHeight, endHeight uint64,
consumer func(*exec.StreamEvent) error) (uint64, error) {
// Assume that we have seen the previous block before start to have ended up here
// NOTE: this will underflow when start is 0 (as it often will be - and needs to be for restored chains)
// however we at most underflow by 1 and we always add 1 back on when returning so we get away with this.
lastHeightSeen := startHeight - 1
err := ees.eventsProvider.IterateStreamEvents(&startHeight, &endHeight,
func(blockEvent *exec.StreamEvent) error {
if blockEvent.EndBlock != nil {
lastHeightSeen = blockEvent.EndBlock.GetHeight()
}
return consumer(blockEvent)
})
// Returns the appropriate _next_ starting block - the one after the one we have seen - from which to stream next
return lastHeightSeen + 1, err
}
Tx
Tx is used to extract a TX data with the specified TxHash. Note it can wait for a Tx by set TxRequest.Wait=True
type TxRequest struct {
// Height of block required
TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,1,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"`
// Whether to wait for the block to become available
Wait bool `protobuf:"varint,2,opt,name=Wait,proto3" json:"Wait,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
call stack
github.com/hyperledger/burrow/rpc/rpcevents.(*executionEventsServer).Tx at execution_events_server.go:43
github.com/hyperledger/burrow/rpc/rpcevents._ExecutionEvents_Tx_Handler.func1 at rpcevents.pb.go:821
github.com/hyperledger/burrow/rpc.unaryInterceptor.func1 at grpc.go:29
github.com/hyperledger/burrow/rpc/rpcevents._ExecutionEvents_Tx_Handler at rpcevents.pb.go:823
google.golang.org/grpc.(*Server).processUnaryRPC at server.go:1024
google.golang.org/grpc.(*Server).handleStream at server.go:1313
google.golang.org/grpc.(*Server).serveStreams.func1.1 at server.go:722
runtime.goexit at asm_amd64.s:1357
- Async stack trace
google.golang.org/grpc.(*Server).serveStreams.func1 at server.go:720